003课程设计报告10065012舒焕.docx

上传人:b****8 文档编号:9845699 上传时间:2023-02-07 格式:DOCX 页数:18 大小:148.04KB
下载 相关 举报
003课程设计报告10065012舒焕.docx_第1页
第1页 / 共18页
003课程设计报告10065012舒焕.docx_第2页
第2页 / 共18页
003课程设计报告10065012舒焕.docx_第3页
第3页 / 共18页
003课程设计报告10065012舒焕.docx_第4页
第4页 / 共18页
003课程设计报告10065012舒焕.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

003课程设计报告10065012舒焕.docx

《003课程设计报告10065012舒焕.docx》由会员分享,可在线阅读,更多相关《003课程设计报告10065012舒焕.docx(18页珍藏版)》请在冰豆网上搜索。

003课程设计报告10065012舒焕.docx

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的多少倍来实现运算。

但还不是很完美,在运算当中如果出现溢出,就会出错,但我现在还不知道怎么处理,只有最后结果溢出,才能处理。

不过在以后的学习中,我还会跟加努力的学习。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 文学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1