003课程设计报告10065012舒焕.docx
- 文档编号:9845699
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:18
- 大小:148.04KB
003课程设计报告10065012舒焕.docx
《003课程设计报告10065012舒焕.docx》由会员分享,可在线阅读,更多相关《003课程设计报告10065012舒焕.docx(18页珍藏版)》请在冰豆网上搜索。
003课程设计报告10065012舒焕
表达式类型的实现
一目的
熟练掌握《数据结构》课程的相关知识,完成一个具有一定难度的综合设计题目,熟练使用c/c++语言进行程序设计,并且规范完成课程设计报告。
巩固《数据结构》里的字符串,树等理论知识的理解,掌握现实复杂问题的分析建模和解决方法,提高利用计算机分析解决综合性实际问题的基本能力。
二需求分析
1、功能
1、将前缀表达式输入到字符串数组中,并且存储到二叉树中。
2、将二叉树中的表达式以中缀的表达式形式输出,有必要的地方加()。
3、对存储前缀表达式的字符串数组进行查询,有未知变量的进行赋值,并且赋值完后存储到该字符串数组中。
并且更新二叉树里的数据。
4、对已经赋值完了的二叉树进行求值。
2、输入
输入的形式以字符串的形式输入到字符串数组中,并且输入的数字字符都是个位数的运算,不能执行十位以上的运算。
可以输入未知变量,如a,b,c,当对未知变量赋值时,未知变量可以是十位以上的数字,但在运算过程中,结果不得超过256,也就是asc码的范围。
例如输入0;a;-91;+a*b5;+-9/62-ab4。
3、输出
该程序的输出分为两步,第一步:
将前缀表达式转化为中缀表达式,存储到字符串数组中,并输出;第二步:
输出表达式测试的结果,并判断是否正确。
对上面的输入,正确的输出应该为0;a;9-1;a+b*5;9-6/2*(a-b)+4;
三概要设计
1、变量定义
宏定义的有,MAXSTR,表示表达式的长度最大限度。
全局变量定义,char类型的str[MAXSTR],用来存储前缀表达式;char类型的str1[MAXSTR],用来存储中缀表达式,并且有必要加括号的时候也包含括号;结构体类型的树和全局变量树指针T,具体定义如下:
typedefstructBitNode{
unsignedchardata;
intstatus;
structBitNode*lchild,*rchild;
}BitNode,*BitTree;
Int类型的overflow,表示当数据大于256时,溢出,不能用符号的asc码表示,需要做一定的处理,int类型的m,用来存储溢出时是256的多少倍。
2、模块设计
模块分为四个模块,前缀表达式的输入模块,中缀表达式输出模块(必要时带号),给未知变量赋值模块,求值模块。
1、前缀表达式输入模块分为两个函数
voidinput()输入前缀表达式函数,判断前缀表达式的正确性,正确之后存储到全局变量str中,
voidcreatBT(BitTree&T1,int&i),将前缀表达式存储到二叉树中。
2、中缀表达式输出模块的函数为
voidout_express(BitTreeT,int&len)
以中缀的形式读取二叉树中的数据,并判断运算符的优先级,在必要的地方加入括号,存储到str1数组中,
voidout_express(BitTreeT,int&len)函数中嵌套有
charprecedence(charzifu_child,charzifu_parents)函数,
判断运算符的优先级,其中
charprecedence(charzifu_child,charzifu_parents)又嵌套
intcharToint(charzifu)函数
intcharToint(charzifu)将运算符的优先级用数字来表示,并且比较大小。
3、未知变量赋值模块包含两个函数
voidassignment()
函数将str[]数组中的未知变量赋值并且将赋值以后的数据存储到str[]数组中
voidcreatBT(BitTree&T1,int&i)
以中缀的形式存储到二叉树中。
4、求值模块函数为
voidcout(BitTree&T1)
该函数将结果转化为字符并且存储在二叉树的头结点中。
四详细设计
1、变量定义
#defineMAXSTR50表示表达式的长度最大限度
typedefstructBitNode{
unsignedchardata;
intstatus;//用来表示表达式的变量1,常量2,运算符3,
structBitNode*lchild,*rchild;
}BitNode,*BitTree;
charstr[MAXSTR];//全局变量,用来存储前缀表达式,用来输入
charstr1[MAXSTR];//全局变量,用来存储中缀表达式,并且输出
intoverflow=0;//判断结果是否超出字符最大的ASCII码数字255;
intm;//用来存储溢出时是256的多少倍。
BitTreeT;//用来存储数据的二叉树指针
2、模块设计
1、前缀表达式输入函数
voidinput(){该函数用存储前缀表达式
inti;
intlength;
intchar_num,int_num;
char_num=0;int_num=0;
printf("请输入正确的前缀表达式");
scanf("%s",str);
if(str[0]!
='+'&&str[0]!
='-'&&str[0]!
='*'&&str[0]!
='/')//第一个不是运算符,则前缀表达式输入错误
printf("表达式输入错误,请从新输入一遍\n");
length=strlen(str);
for(i=0;i { if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/') char_num++; else int_num++; } if(int_num! =char_num+1)//如果变量的个数不是等于运算符的个数,则前缀表达式输入错误 printf("表达式输入错误,请从新输入一遍\n"); }并且存储到二叉树中用到函数voidcreatBT(BitTree&T1,int&i){ T1=(BitTree)malloc(sizeof(BitTree)); if(str[i]=='\0') return; if(str[i]<='9'&&str[i]>='0') { T1->data=str[i]; T1->status=2; T1->lchild=T1->rchild=NULL; } elseif(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')//将运算符存储在根节点 { T1->data=str[i]; T1->status=3; i++; creatBT(T1->lchild,i); i++; creatBT(T1->rchild,i); } elseif(str[i]<='z'&&str[i]>='a') { T1->data=str[i]; T1->status=1; T1->lchild=T1->rchild=NULL; } }该函数将数组str中的表达式存储到二叉树中 2、中缀表达式输出函数 voidout_express(BitTreeT,int&len){ chartemp; if(! T)return; if(T->lchild){ if(T->lchild->status! =3)str1[len++]=T->lchild->data; else{ temp=precedence(T->lchild->data,T->data);判断做孩子与根节点运算符的优先级,必要时加上括号。 并且存储到str1[]数组中 switch(temp){ case'<': str1[len++]='('; out_express(T->lchild,len); str1[len++]=')'; break; case'=': case'>': out_express(T->lchild,len); break; } } } str1[len++]=T->data; if(T->rchild){ if(T->rchild->status! =3)str1[len++]=T->rchild->data; else{ temp=precedence(T->rchild->data,T->data); switch(temp){ case'<': str1[len++]='('; out_express(T->rchild,len); str1[len++]=')'; break; case'=': case'>': out_express(T->rchild,len); break; } } } }其中嵌套函数charprecedence(charzifu_child,charzifu_parents){ chartemp; intm,n; m=charToint(zifu_child); n=charToint(zifu_parents); if(m-n>0) { temp='>'; returntemp; } elseif(m-n==0) { temp='='; returntemp; } else{ temp='<'; returntemp; } }再嵌套函数intcharToint(charzifu){ if(zifu=='+'||zifu=='-') return1; if(zifu=='*'||zifu=='/') return2; return0; } 3、赋值函数 voidassignment(){ charbianliang[MAXSTR]; intk=1,j,str_length; intc; str_length=strlen(str); for(inti=0;i if(str[i]<='z'&&str[i]>='a')搜索变量并且存储到bianliang【】数组中 { bianliang[k]=str[i]; for(j=1;j if(bianliang[j]==bianliang[k])变量有重复就舍去, { bianliang[k]='\0'; k--; } k++; } for(j=1;j { printf("第%d个变量%c赋值为: \n",j,bianliang[j]); scanf("%d",&c);给变量赋值 for(i=0;i if(str[i]==bianliang[j])赋值以后存储到str【】数组中 str[i]=c+'0'; } printf("用来测试赋值是否成功%s\n",str); } 4、求值函数 voidcout(BitTree&T1){用后跟遍历的方法求二叉树中的值,并且用递归的方法 inta,b,result; if(! T1->lchild&&! T1->rchild) return; if(T1->lchild->status==3) cout(T1->lchild); if(T1->rchild->status==3) cout(T1->rchild); if(T1->lchild->status==2&&T1->rchild->status==2) { a=T1->lchild->data-48; b=T1->rchild->data-48; switch(T1->data) { case'+': result=a+b;break; case'-': result=a-b;break; case'*': result=a*b;break; case'/': result=a/b;break; } if(result+48>255)//溢出,超出asc码的范围,特殊处理 { m=(result+48)/256; overflow=1; result=result+48-256*m; } T1->data=result+48; T1->status=2; } } 五调试分析 1、输入模块 输入前缀表达式时,基本的判断了前缀表达式是否正确,但更深层次的判断还没有实现。 比如首字符必须为运算符,运算符比变量少一个。 这种判断能实现,但如果像*222*这种前缀表达式就不能判断,会使程序出问题。 现在还没得到解决。 2、中缀表达式输出 通过中根遍历的方法,比较运算符的优先级,在需要时加上括号,并且都存储到数组str1[]主要还是递归的方法,这个函数没出什么问题。 3、赋值函数 首先在数组str中找出未知变量,存储到bianliang数组中,重复的未知变量记录一次,利用循环在str数组中找到与bianliang数组中对应的字符并赋值。 这时,出现了一个问题,就是当赋值时,用到scanf("%c",&c),str[i]=c出错,然后更改c为int型的数据,并且用scanf("%d",&c);赋值str[i]=c+'0',这时才正确,虽然改对了,但还是不懂为什么。 4、求值函数 只有一个问题,就是当数据结果大于256时,超出了asc码的范围,就需要用到溢出overflow变量来处理,将结果减去溢出256的多少倍,就能用符号存储了,在输出结果时再加上减去的数据就可以了。 六测试结果 开始运行程序,显示菜单,选择1,输入表达式, 表达式输入错误后,又回到菜单,选择1,重新输入表达式0,并且选择2,查看表达式 又重新输入1,测试任务书里给的数据,查看程序结果是否正确。 继续测试表达式数据-91. 测试有未知变量的表达式数据+a*b5。 测试有未知数据并且转换成中缀表达式有括号的表达式数据+-9*/62-ab4。 选择3,给表达式赋值,然后选择4,给表达式求值。 测试若果结果超出asc码的范围,计算结果是否正确。 选择菜单之外的选择时,提示输入错误。 选择0,结束程序运行。 七用户使用说明 1、本程序的运行环境为vc6.0执行文件为expressText.cpp 2、用户界面为 3、用户只需要根据提示来输入。 4、若要退出只需输入0。 八课程设计总结 在这次课程设计中,我学会了很多东西,并且也温习了之前所学的一些知识。 对二叉树的运用,以及在遍历二叉树时所用到的递归算法。 尤其在前缀表达式转化为中缀表达式和二叉树求值的时候,递归用得特是时候,非常的好。 其次在赋值模块里,也通过全局变量数组来存储变量,并且在for循环的作用下,给每一个变量赋值,然后存储到二叉树中,最后求值。 不过,在这次程序设计中,也遇到了跟多困难,主要是在求值模块里,当数据超出范围,也就是asc码的范围256,就要通过减去256的多少倍来实现运算。 但还不是很完美,在运算当中如果出现溢出,就会出错,但我现在还不知道怎么处理,只有最后结果溢出,才能处理。 不过在以后的学习中,我还会跟加努力的学习。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 003 课程设计 报告 10065012 舒焕