表达式求值c++ 数据结构课设报告
- 格式:doc
- 大小:202.00 KB
- 文档页数:23
实验报告课程名:数据结构(C语言版)实验名:表达式求值姓名:班级:学号:时间:2014.10.25一实验目的与要求1. 了解栈的应用2. 利用栈进行算术表达式求值二实验内容1.以字符串的形式给出一个算术表达式, 计算出该算术表达式的值。
2.表达式中可能出现”+”, ”−”, ”∗”, ”/”, ”(”, ”)”。
三实验结果与分析分析:r:读入字符t:栈顶字符r( ) # 低优先运算符高优先运算符( 入栈出栈错误入栈入栈) 错误错误错误错误错误t # 入栈错误结束入栈入栈低优先运算符入栈出栈+运算出栈+计算出栈+计算入栈高优先运算符入栈出栈+运算出栈+计算出栈+计算出栈+计算1, 入栈2, 错误3, 出栈4, 出栈+计算5, 结束( ) # 低优先运算符高优先运算符( 1 3 2 1 1) 2 2 2 2 2# 1 2 5 1 1低优先运算符 1 4 4 4 1高优先运算符 1 4 4 4 4此实验可用两个栈和数组来实现,一个操作栈,一个数字栈,两个栈的字符进行优先权比较可得到5种结果。
首先置操作栈为空栈,表达式起始符“#”作为数字栈的栈底元素,依次读入表达式的每个字符,若是操作字符进操作栈,若是数字进数字栈,操作栈和数字栈的栈顶元素比较优先权后进行相应操作,直至结束,最后输出值即可。
实验程序:#include<stdio.h>#include<stdlib.h>#include<string.h>int change(char c)//字符转换{int j=-1;switch(c){case '(':j=0;break;case ')':j=1;break;case '#':j=2;break;case '+':j=3;break;case '-':j=3;break;case '*':j=4;break;case '/':j=4;break;}return(j);}int compu(int x,int y,char c)//数字计算转换{int j=-1;switch(c){case '+':j=x+y;break;case '-':j=x-y;break;case '*':j=x*y;break;case '/':j=x/y;break;}return(j);}void get(char a[],int num_op,int method[5][5]){int a_length=strlen(a)+1;//表达式的长度int p=0,num_p=0,op_p=0;int *num_s=(int *)malloc((a_length)*sizeof(int));// char *op_s=(char *)malloc((a_length)*sizeof(int));// op_s[op_p]='#';op_p++;//进字符栈int k=-1;//输出结果判断int ox,oy;while(1){char c=a[p];//将表达式中的字符一个一个赋值给cif(c>='0'&&c<='9')//判断是不是数字{num_s[num_p]=c-48;//将Ascll码转换成对应数字num_p++;//进数字栈p++;//代表表达式的位置开始为0指向第一位}else{int t=method[change(op_s[op_p-1])][change(c)];//将5种操作的一种传给tswitch(t){case 1:op_s[op_p]=c;op_p++;p++;break;case 2:k=0;break;case 3:op_p--;p++;break;case 4:ox=num_s[num_p-2];oy=num_s[num_p-1];num_p=num_p-2;num_s[num_p]=compu(ox,oy,op_s[op_p-1]);//将计算的值存入num_s[]num_p++;//入数字栈op_p--;break;case 5:k=1;break;}}if(k>=0)//跳出循环{break;}}switch(k)//0错误,1输出结果{case 0:printf("表达式错误!");break;case 1:printf("%s=%d\n",a,num_s[num_p-1]);break;}}int main(int argc,char *argv[]){ char a[20];puts("请输入个位数的表达式:");gets(a);int num_op=5;//表示操作的种数int method[5][5]={{1,3,2,1,1},{2,2,2,2,2},{1,2,5,1,1},{1,4,4,4,1},{1,4,4,4,4}};//1表示入栈,2表示错误,//3表示出栈,4表示出栈+计算,//5表示结束get(a,num_op,method);return 0;}图1.表达式求值运行结果。
XXXXXX大学《数据结构》课程设计报告班级:学号:姓名:指导老师:目录一算术表达式求值一、需求分析二、程序得主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结算术表达式求值一、需求分析一个算术表达式就是由操作数(operand)、运算符(operator)与界限符(delimiter)组成得。
假设操作数就是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号与表达式起始、结束符“#”,如:#(7+15)*(23—28/4)#。
引入表达式起始、结束符就是为了方便.编程利用“算符优先法”求算术表达式得值.二、程序得主要功能(1)从键盘读入一个合法得算术表达式,输出正确得结果。
(2)显示输入序列与栈得变化过程。
三、程序运行平台Visual C++6、0版本四、数据结构本程序得数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针intstacksize; //栈得长度};intInitStack (SqStack &s) //建立一个空栈S{if (!(s、base= (char *)malloc(50*sizeof(char))))exit(0);s、top=s、base;s、stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s、top==s、base) //栈为空得时候返回ERROR{ﻩ printf("运算符栈为空!\n");ﻩ return ERROR;}elsee=*(s、top-1); //栈不为空得时候用e做返回值,返回S得栈顶元素,并返回OK returnOK;}int Push(SqStack&s,char e) //运算符入栈{if (s、top—s、base >= s、stacksize)ﻩ{printf("运算符栈满!\n");ﻩs、base=(char*)realloc(s、base,(s、stacksize+5)*sizeof(char));//栈满得时候,追加5个存储空间if(!s、base)exit (OVERFLOW);s、top=s、base+s、stacksize;s、stacksize+=5;}ﻩ*(s、top)++=e;//把e入栈ﻩreturn OK;}int Pop(SqStack &s,char &e) //运算符出栈{if (s、top==s、base) //栈为空栈得时候,返回ERROR{printf("运算符栈为空!\n”);ﻩ return ERROR;}else{ﻩﻩe=*-—s、top;//栈不为空得时候用e做返回值,删除S得栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack&s)//运算符栈得遍历{ﻩchar *t;ﻩt=s、base;ﻩif (s、top==s、base){ﻩ printf(”运算符栈为空!\n”); //栈为空栈得时候返回ERRORreturn ERROR;}while(t!=s、top){ﻩﻩprintf(" %c",*t); //栈不为空得时候依次取出栈内元素t++;ﻩ}return ERROR;}(2)数字栈部分:struct SqStackn//定义数栈{int *base; //栈底指针int*top; //栈顶指针int stacksize; //栈得长度};intInitStackn (SqStackn &s) //建立一个空栈S{s、base=(int*)malloc(50*sizeof(int));if(!s、base)exit(OVERFLOW);//存储分配失败s、top=s、base;s、stacksize=50;return OK;}int GetTopn(SqStackn s,int&e) //数栈取栈顶元素{if(s、top==s、base){printf("运算数栈为空!\n");//栈为空得时候返回ERRORﻩ return ERROR;}elseﻩe=*(s、top-1);//栈不为空得时候,用e作返回值,返回S得栈顶元素,并返回OKreturnOK;}int Pushn(SqStackn &s,int e) //数栈入栈{if(s、top—s、base>=s、stacksize){ﻩﻩprintf("运算数栈满!\n");//栈满得时候,追加5个存储空间ﻩs、base=(int*)realloc (s、base,(s、stacksize+5)*sizeof(int));if(!s、base) exit (OVERFLOW);ﻩs、top=s、base+s、stacksize;//插入元素e为新得栈顶元素s、stacksize+=5;}*(s、top)++=e; //栈顶指针变化returnOK;}int Popn(SqStackn &s,int &e)//数栈出栈{ﻩif (s、top==s、base){ﻩ printf("运算符栈为空!\n");//栈为空栈得视时候,返回ERRORﻩ return ERROR;ﻩ}else{ﻩﻩe=*—-s、top;//栈不空得时候,则删除S得栈顶元素,用e返回其值,并返回OK ﻩreturnOK;}}int StackTraversen(SqStackn &s)//数栈遍历{ﻩint*t;ﻩt=s、base ;ﻩif(s、top==s、base)ﻩ{printf("运算数栈为空!\n”);//栈为空栈得时候返回ERRORﻩ return ERROR;ﻩ}ﻩwhile(t!=s、top)ﻩ{printf(” %d”,*t); //栈不为空得时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。
2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。
该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。
1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。
下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。
分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。
数据结构课程设计四则运算表达式求值(C语⾔版) 明⼈不说暗话,直接上,输⼊提取码z3fy即可下载。
⽂件中包含程序,程序运⾏⽂件,设计报告和测试样例,应有尽有,欢迎⼩伙伴们在中下载使⽤。
本课程设计为四则运算表达式求值,⽤于带⼩括号的⼀定范围内正负数的四则运算标准(中缀)表达式的求值。
注意事项:1、请保证输⼊的四则表达式的合法性。
输⼊的中缀表达式中只能含有英⽂符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及⼩数点“.”,输⼊“=”表⽰输⼊结束。
例如9+(3-1)*3.567+10/2=,特别是请勿输⼊多余空格和中⽂左右括号。
2、输⼊的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。
3、请保证输⼊的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。
本课程设计中操作数是C语⾔中的双精度浮点数类型。
4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。
下⾯的程序正常运⾏需要在上⾯的百度⽹盘中下载相应⽂件,否则⽆法正常使⽤哦。
1/*本程序为四则运算表达式求值系统,⽤于计算带⼩括号的四则运算表达式求值。
2具体算法:3先将字符串处理成操作单元(操作数或操作符),再利⽤栈根据四则运算4的运算法则进⾏计算,最后得出结果。
*/56 #include<stdio.h>7 #include<ctype.h>8 #include<stdlib.h>9 #include<string.h>10 #include<stdlib.h>11 #include<ctype.h>1213const int Expmax_length = 1001;//表达式最⼤长度,可根据适当情况调整14struct Ope_unit15 {//定义操作单元16int flag;//=1表⽰是操作数 =0表⽰是操作符 -1表⽰符号单元17char oper;//操作符18double real;//操作数,为双精度浮点数19 };2021void Display();//菜单22void Instru(); //使⽤说明23int Check(char Exp_arry[]);24void Evalua(); //先调⽤Conver操作单元化,再调⽤Calculate函数计算结果并输出25int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元26int Isoper(char ch);//判断合法字符(+ - * / ( ) =)27int Ope_Compar(char ope1,char ope2);//操作符运算优先级⽐较28double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//⽤栈计算表达式结果29double Four_arithm(double x,double y,char oper);//四则运算3031int main()32 {33int select;34while(1)35 {36 Display();37 printf("请输⼊欲执⾏功能对应的数字:");38 scanf("%d",&select);39 printf("\n");40switch(select)41 {42case1: Evalua(); break;43case2: Instru(); break;44case0: return0;45default : printf("⽆该数字对应的功能,请重新输⼊\n");46 system("pause");47 }48 }49return0;50 }5152int Check(char Exp_arry[])53 {//检查是否有⾮法字符,返回1表⽰不合法,0表⽰合法54int Explength=strlen(Exp_arry),i;55for(i=0;i<Explength;i++)56 {57if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))58return1;59if(isdigit(Exp_arry[i]))60 {61int Dig_number=0,Cur_positoin=i+1;62while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')63 {64 Dig_number++;65 Cur_positoin++;66 }67if(Dig_number >= 16)//最多能够计算15位有效数字68return1;69 }70 }71return0;72 }7374void Evalua()75 {//先调⽤Conver函数将字符串操作单元化,再调⽤Calculate函数计算结果并输出76char Exp_arry[Expmax_length];77int flag=0;//假设刚开始不合法,1表达式合法,0不合法78struct Ope_unit Opeunit_arry[Expmax_length];7980 getchar();//吃掉⼀个换⾏符81 printf("请输⼊四则运算表达式,以=结尾:\n");82 gets(Exp_arry);83 flag=Check(Exp_arry);84if(flag)85 printf("该表达式不合法!\n");86else87 {88int Opeunit_count = Conver(Opeunit_arry,Exp_arry);89double ans = Calculate(Opeunit_arry,Opeunit_count,flag);90if(flag)91 {92 printf("计算结果为:\n");93 printf("%s%lf\n",Exp_arry,ans);94 }95else96 printf("该表达式不合法!\n");97 }98 system("pause");99 }100101int Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])102 {//将字符串操作单元化103int Explength=strlen(Exp_arry);104int i,Opeunit_count=0;105for(i=0;i<Explength;i++)106 {107if(Isoper(Exp_arry[i]))//是操作符108 {109 Opeunit_arry[Opeunit_count].flag=0;110 Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];111 }112else//是操作数113 {114 Opeunit_arry[Opeunit_count].flag=1;115char temp[Expmax_length];116int k=0;117for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++)118 {119 temp[k++]=Exp_arry[i];120 }121 i--;122 temp[k]='\0';123 Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数124125//负数126if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0127 && Opeunit_arry[Opeunit_count-1].oper=='-')128 {129 Opeunit_arry[Opeunit_count-1].flag = -1;130 Opeunit_arry[Opeunit_count].real *= -1;131 }// -9132if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0133 && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 134 && Opeunit_arry[Opeunit_count-2].oper !=')')135 {136 Opeunit_arry[Opeunit_count-1].flag = -1;137 Opeunit_arry[Opeunit_count].real *= -1;138 }// )-9139140//正数141if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0142 && Opeunit_arry[Opeunit_count-1].oper=='+')143 {144 Opeunit_arry[Opeunit_count-1].flag = -1;145 }// +9146if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0147 && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0148 && Opeunit_arry[Opeunit_count-2].oper !=')')149 {150 Opeunit_arry[Opeunit_count-1].flag = -1;151 }// )+9152 Opeunit_count++;153 }154 }155/*for(i=0;i<Opeunit_count;i++)156 {//查看各操作单元是否正确,1是操作数,0是操作符157 if(Opeunit_arry[i].flag == 1)158 printf("该单元是操作数为:%lf\n",Opeunit_arry[i].real);159 else if(Opeunit_arry[i].flag == 0)160 printf("该单元是操作符为:%c\n",Opeunit_arry[i].oper);161 else162 printf("该单元是负号符为:%c\n",Opeunit_arry[i].oper);163 }*/164return Opeunit_count;165 }166167double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)168 {//根据运算规则,利⽤栈进⾏计算169int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指⽰器,oS_pointer为操作符栈顶指⽰器170double Dig_stack[Expmax_length];//操作数栈(顺序存储结构)171char Ope_stack[Expmax_length];//操作符栈172173for(i=0;i<Opeunit_count-1;i++)174 {175if( Opeunit_arry[i].flag != -1 )176 {177if(Opeunit_arry[i].flag)//是操作数178 {179 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//⼊操作数栈180//printf("%lf\n",Digit[dS_pointer-1]);181 }182else//是操作符 + - * / ( )183 {184//操作符栈为空或者左括号⼊栈185if(oS_pointer==0 || Opeunit_arry[i].oper=='(')186 {187 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;188//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);189 }190else191 {192if(Opeunit_arry[i].oper==')')//是右括号将运算符⼀直出栈,直到遇见左括号193 {194 oS_pointer--;//指向栈顶195 dS_pointer--;//指向栈顶196while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)197 {198 Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 199 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈200201 dS_pointer--;//前⼀个操作数出栈202//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);203 }204 oS_pointer--;//左括号出栈205206 oS_pointer++;//恢复指向栈顶之上207 dS_pointer++;208 }209else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素⽐较210 {211 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;212//printf("%oS_pointer\Ope_u_count",Operator[oS_pointer-1]);213 }214else//运算符出栈,再将该操作符⼊栈215 {216 oS_pointer--;//指向栈顶217 dS_pointer--;//指向栈顶218while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1) 219 {//当前操作符⽐栈顶操作符优先级⾼220 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 221 Ope_stack[oS_pointer--]);222 dS_pointer--;223//printf("操作数栈顶元素等于%lf\n",Digit[dS_pointer]);224 }225 oS_pointer++;//恢复指向栈顶之上226 dS_pointer++;227 Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;228 }229 }230 }231 }232 }233/*for(i=0;i<oS_pointer;i++)234 printf("操作符栈%oS_pointer\Ope_u_count",Operator[i]);235 for(i=0;i<dS_pointer;i++)236 printf("操作数栈%lf\n",Digit[i]);*/237 oS_pointer--;//指向栈顶元素238 dS_pointer--;//指向栈顶元素239while(oS_pointer != -1)240 {241 Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer], 242 Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈243 dS_pointer--;//前⼀个操作数出栈244//printf("操作数栈顶元素为%lf\Ope_u_count",Digit[dS_pointer]);245 }246//printf("%dS_pointer,%dS_pointer\n",oS_pointer,dS_pointer);247if(oS_pointer==-1 && dS_pointer==0)248 flag=1;//为1表⽰表达式合法249return Dig_stack[0];250 }251252int Ope_Compar(char ope1,char ope2)253 {//操作符运算优先级⽐较254char list[]={"(+-*/"};255int map[5][5]={//先⾏后列,⾏⽐列的运算级优先级低为0,⾼为1256// ( + - * /257/* ( */1,0,0,0,0,258/* + */1,0,0,0,0,259/* - */1,0,0,0,0,260/* * */1,1,1,0,0,261/* / */1,1,1,0,0 };262int i,j;263for(i=0;i<5;i++)264if(ope1==list[i]) break;265for(j=0;j<5;j++)266if(ope2==list[j]) break;267return map[i][j];268 }269270double Four_arithm(double x,double y,char oper)271 {//四则运算272switch(oper)//保证不含其它运算符273 {274case'+': return x+y;275case'-': return x-y;276case'*': return x*y;277case'/': return x/y;//y不能为0278default : return0;279 }280 }281282int Isoper(char ch)283 {//判断合法字符 + - * / ( ) =284if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=')285return1;286return0;287 }288289void Display()290 {//打印菜单291 system("cls");292 printf("/******************************************************************************/\n");293 printf("\t\t 欢迎使⽤本四则运算表达式求值系统\n");294 printf("\n\t说明:建议请您先阅读使⽤说明,再输⼊相应的数字进⾏操作,谢谢配合!\n"); 295 printf("\n\t\t1 四则运算表达式求值\n");296 printf("\n\t\t2 使⽤说明\n");297 printf("\n\t\t0 退出\n");298 printf("/******************************************************************************/\n");299 }300301void Instru()302 {//打印使⽤说明303 FILE *fp;304char ch;305if( ( fp=fopen("使⽤说明.txt","r") ) == NULL)306 {307 printf("⽂件打开失败!\n");308 exit(0);309 }310for(; (ch = fgetc(fp)) != EOF; )311 putchar(ch);312 fclose(fp);313 printf("\n");314 system("pause");315 }。
表达式求值实验报告西南大学数据结构实验报告学院:专业:班级:姓名:学号:实验报告一、实验题目:表达式表达式二、实验目的和建议:目的:(1)通过该算法的设计思想,熟识栈的特点和应用领域方法;(2)通过对波函数优先法对算术表达式表达式的算法继续执行过程的模拟,认知在继续执行适当栈的操作方式时的变化过程。
(3)通过程序设计,进一步熟识栈的基本运算函数;(4)通过自己动手同时实现算法,强化从伪码算法至c语言程序的同时实现能力。
建议:(1)采用栈的顺序存储则表示方式;(2)采用波函数优先法;(3)用c语言同时实现;(4)从键盘输入一个符合要求的算术表达式,输入恰当的结果。
三、实验过程:#include#include#include#include#include#include#include#include#include#inclu de#include//函数结果状态代码#definetrue1#definefalse0#defineok1#defineerror0#defineinfeasible-1typedefintstatus;//status就是函数的类型,其值就是函数结果状态代码,如ok等typedefintelemtype;constintstack_init_size=100;constintstackincrement=10;typed efstruct{elemtype*base;elemtype*top;intstacksize;}stack;statusinitstack(stack&s){//构造一个空栈ss.base=(elemtype*)malloc(stack_init_size*sizeof(elemtype));if(!s.base)exit(er ror);s.top=s.base;s.stacksize=stack_init_size;returnok;}statuspush(stack&s,ele mtypee){//插入元素e为新的栈顶元素if(s.top-s.base>=s.stacksize){s.base=(elemtype*)realloc(s.base,(s.stacksize+stackincrem ent)*sizeof(elemtype));if(!s.base)exit(overflow);s.top=s.base+s.stacksize;s.st acksize+=stackincrement;}*s.top++=e;returnok;}statuspop(stack&s,elemtype&e){//若栈不空,则删除,用e返回其值,并返回ok;否则返回errorif(s.top==s.base)returnerror;e=*--s.top;returnok;}statusgettop(stack&s){//若栈不空,用e返回s的栈顶元素,并返回ok;否则返回errorif(s.top==s.base)returnerror;return*(s.top-1);}operate.h:#include\statusin(charc){//辨别c与否为运算符if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')returnok;elsereturnerror;}statusoper ate(inta,charc,intb){//二元运算switch(c){case'+':returna+b;break;case'-':returna-b;break;case'*':returna*b;break;case'/':if(b==0){printf(\(提示信息:存有除数为零错误)\\n\);returnerror;}//除数无法为零elsereturna/b;break;}}charprecede(chara,charb){//波函数间优先关系switch(a){case'+':switch(b){case'+':return'>';break;case'-':return'>';break;case'*':return'';break;case'#':return'>';break;}break;case'-':switch(b){case'+':return'>';break;case'-':return'>';break;case'*':return'';break;case'#':return'>';break;}break;case'*':switch(b){case'+':return'>';break;case'-':return'>';break;case'*':return'>';break;case'/':return'>';break;case'(':return'';break;case'#':return'>';break;}break;case'/':switch(b){case'+':return'>'; break;case'-':return'>';break;case'*':return'>';break;case'/':return'>';break;case'(':return'';break;case'#':return'>';break;}break;case'(':switch(b){case'+':return'';b reak;case'-':return'>';break;case'*':return'>';break;case'/':return'>';break;case')':return'>';break;case'#':return'>';break;}break;case'#':switch(b)。
数据结构表达式求值实验报告数据结构表达式求值实验报告⒈引言本实验旨在研究和实现数据结构中表达式求值的算法。
表达式求值是计算机科学中常见的问题,对于计算机程序的正确性和性能具有重要影响。
本报告将详细介绍实验设计、实验步骤、实验结果及分析,并对实验过程中遇到的问题进行讨论。
⒉实验设计⑴实验目的本实验的目的是实现一个可以对常见的算术表达式进行求值的算法,包括支持基本的加减乘除运算符和括号。
⑵实验环境●操作系统:Windows 10●开发语言:C++●开发工具:Visual Studio 2019⑶数据结构设计为了实现表达式求值的算法,我们需要设计适当的数据结构来存储和处理表达式。
本实验中,我们选择使用栈来实现表达式求值。
●表达式栈:用于存储操作数和运算符。
●运算符栈:用于存储运算符。
⑷算法设计表达式求值的算法可以分为以下几个步骤:●遍历表达式,逐个处理操作数和运算符:●如果是操作数,入表达式栈。
●如果是运算符,与运算符栈栈顶元素进行比较,根据优先级决定如何处理。
●当表达式遍历完成后,依次处理剩余的运算符。
●最终表达式栈中的元素即为求值结果。
⒊实验步骤⑴数据结构实现根据设计,我们首先实现表达式栈和运算符栈的数据结构,包括入栈、出栈等操作。
⑵表达式输入与预处理用户输入待求值的表达式,进行预处理,去除空格、验证表达式的合法性等。
⑶表达式求值算法实现根据前述的算法设计,实现表达式求值的算法,利用表达式栈和运算符栈来处理表达式。
⑷测试与结果分析对于不同的测试用例,进行表达式求值的测试,并分析结果的正确性和性能。
⒋实验结果与分析经过实验测试,我们得到了表达式求值的结果。
结果显示,我们的算法能够正确地求得表达式的值,而且性能良好。
⒌讨论与总结在实验过程中,我们遇到了一些问题,并进行了讨论和解决。
通过这个实验,我们更加深入地理解了表达式求值的算法,并对数据结构的应用有了更清晰的认识。
附件:无法律名词及注释:●无。
数据结构实训总结报告题目:表达式求值学生姓名:学生学号:专业班级:指导老师:目录1.课题分析 .....................................................................1.1需求分析..............................................................1. 2设计要求............................................................2.总体设计.......................................................................2.1主程序的流程.....................................................3.详细设计(步骤及代码实现) ...................................3. 1判断运算符优先级..............................................3. 2中缀表达式转后缀表达式..................................3. 3后缀表达式求值.................................................. 4.测试结果 .................................................................... 5.心得体会 .................................................................... 6.参考文献 ....................................................................1.课题分析1.1需求分析(1)栈“后进先出”的特点。
实验二表达式求值
实验内容:
用算符优先法设计一个具有加、减、乘、除四功能的计算程序。
实验目的与要求:
掌握栈的数据结构和基本操作。
实验原理:
1.表达式是由操作数,运算符和界限符组成。
2.实现算符优先算法,实用两个工作栈。
一个叫OPTR,用以寄存运算符;一个叫OPND,用以寄存操作数或运算结果。
3.算法的基本思路:
(1)首先置操作数栈为空栈,表达式起始符#作为运算符栈的栈底元素;
(2) 依次读入表达式中的每个字符,通过运算符判断函数In()使操作数进OPND 栈;
(3)通过函数Precede()将运算符与OPTR栈的栈底运算符比较出优先权,若栈顶元素优先权低则输入下个操作数到OPND,若两优先权相等,脱号并接受下一个字符,若栈顶元素优先高,退栈并将运算结果(通过函数Operate()运算)入栈。
循环上述操作直到表达式求值结束。
(4)返回运算结果。
4.所用的函数及作用:
InitStack():构造一个空栈
Push():插入元素进栈
GetTop():返回栈顶元素
Precede():运算符优先权进行判断
Pop():元素出栈
Operate():运算操作数
5. 测试结果与分析
上述程序在Visual C++ 6.0环境下加以实现。
经过多次测试,程序运行正确。
运行结果。
如图所示:
6. 收获与体会
通过这次课程设计:
1.我又进一步巩固了C语言的基础,尤其是栈。
2.算法中需要建很多的函数,队提高了自己的编程能力有帮助,
3.程序不够简洁,还有待改进,功能还有待更完善。
题目:计算表达式的值1、问题描述对于给定的一个表达式,表达式中可以包括常数、算术运行符(“+”、“-”、“*”、“/”)和括号,编写程序计算表达式的值。
基本要求:从键盘输入一个正确的中缀表达式,将中缀表达式转换为对应的后缀表达式,计算后缀表达式的值。
提高要求:(1)对于表达式中的简单错误,能够给出提示;(2)不仅提示错误,也能给出错误信息(3)表达式中可以包括单个字母表示的变量(4)能够处理多种操作符(5)实现包含简单运算的计算器(6)实现一个包含简单运算和函数运算的计算器。
2.需求分析软件的基本功能:由键盘输入中缀表达式,程序可以将输入的中缀表达式转换成对应的后缀表达式,并计算后缀表达式的值。
对于在输入时发生的简单错误,程序可以给出提示。
本程序支持整数、小数、多种操作数的处理,可以计算含加、减、乘、除、运算符的表达式,并能判断表达式括号是否匹配。
输入/输出形式:用户可以通过控制台,根据输入提示。
输入形式:①正确的不含字母变量的中缀表达式;②含有简单错误的中缀表达式。
输出形式:①对于正确的中缀表达式,可以输出其转化后的后缀表达式及表达式的计算结果;②对于含有简单错误的中缀表达式,程序将自动输出错误提示,并给出错误信息。
测试数据要求:用户可以输入一个符合要求的中缀表达式,也可以输入一个包含简单错误的表达式。
表达式中可以包括各种类型的常数以及小数等,操作符包括(+、-、*、/),同时表达式还可以包括各种括号。
3.概要设计(1)抽象数据类型:根据题目的要求,考虑用栈类型比较适合。
ADT SeqStackData栈中元素具有相同类型及后进先出特性,相邻元素具有前驱和后继关系OperationSeqStack前置条件:栈不存在输入:无功能:栈的初始化输出:无后置条件:构造一个空栈~ SeqStack前置条件:栈已存在输入:无功能:销毁栈输出:无后置条件:释放栈所占用的存储空间Push前置条件:栈已存在输入:元素值x功能:在栈顶插入一个元素x输出:如果插入不成功,抛出异常后置条件:如果插入成功,栈顶增加了一个元素 Pop前置条件:栈已存在输入:无功能:删除栈顶元素输出:如果删除成功,返回被删元素值,否则,抛出异常后置条件:如果删除成功,栈顶减少了一个元素 GetTop前置条件:栈已存在输入:无功能:读取当前的栈顶元素输出:若栈不空,返回当前的栈顶元素值后置条件:栈不变Empty前置条件:栈已存在输入:无功能:判断栈是否为空输出:如果栈为空,返回1;否则,返回0后置条件:栈不变End ADT4.详细设计(1)实现概要设计的数据类型:采用顺序栈const int StackSize = 50;template <class DataType> //定义模板类SeqStackclass SeqStack{public:SeqStack(); //构造函数,栈的初始化~SeqStack(); //析构函数void Push(T x); //将元素x入栈DataType Pop(); //将栈顶元素弹出DataType GetTop(); //取栈顶元素(并不删除)int Empty(); //判断栈是否为空private:DataType data[StackSize]; //存放栈元素的数组int top; //栈顶元素};(2)主程序以及其它模块的算法描述:这个函数主要调用了实现功能的各个函数。
数据结构课程设计设计说明书算术表达式求值问题学生姓名白子健学号1318014057 班级计本1302 成绩指导教师李军计算机科学与技术系2015年9月10日数据结构课程设计评阅书课程设计任务书2015—2016学年第一学期专业:计算机科学与技术学号:1318014057 姓名:白子健课程设计名称:课程设计Ⅰ---数据结构课程设计设计题目:表达式求值算法的实现完成期限:自2015 年9 月 1 日至2015 年9 月12 日共2 周设计内容及要求:算术表达式求值是程序设计语言编译中的一个基本问题,通过栈实现表达式运算优先级的匹配和运算。
用C/C++语言编程实现任意算术表达式的求值,设计内容要求如下:(1)表达式共有三种基本表示方法:前缀法、中缀法、后缀法。
从表达式的这三种基本方法中任选一种方法进行编程求值。
(2)分析所选的表示方法,根据选定的表示方法确定对应的存储结构和相关算法。
(3)算法要能正确处理算术运算的优先级规则,即: 先括号内,后括号外的规则;运算先乘除,后加减;同级运算从左到右。
如下表达式:50+(6*3+2)要求:(1)用C/C++语言编写一个程序将这组学生成绩输入到计算机中,数据运算的存储逻辑结构为栈。
(2)程序要能正确处理表达式的优先级、输出正确运算结果。
最终设计成果形式为:1、设计好的软件一套;2、撰写一份课程设计说明书一份,打印并装订成册。
指导教师(签字):教研室主任(签字):批准日期:年月日目录1 课题描述 (1)2 设计思路 (2)3 算法设计 (3)4 程序代码 (5)5 测试及分析 (12)6 总结 (13)参考文献 (13)1 课题描述表达式求值是程序设计语言编译中的一个最基本问题。
表达式求值在计算机中的实现是栈结构在计算机中的一个典型应用。
这里使用“算符优先算法”实现表达式求值。
要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式。
数据结构表达式求值实验报告一、实验目的本次实验的主要目的是通过实现表达式求值的程序,深入理解数据结构和算法在解决实际问题中的应用。
具体包括掌握栈这种数据结构的操作和使用,熟悉表达式的转换和计算过程,提高编程能力和问题解决能力。
二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。
三、实验原理表达式求值是程序设计中的一个常见问题,通常采用栈这种数据结构来实现。
表达式可以分为中缀表达式、后缀表达式和前缀表达式。
中缀表达式是我们日常使用的表达式形式,如“2 +3 4”,但直接对中缀表达式求值比较复杂。
而后缀表达式(如“2 3 4 +”)和前缀表达式(如“+2 3 4”)求值相对简单。
因此,在实现表达式求值时,通常先将中缀表达式转换为后缀表达式,然后对后缀表达式进行求值。
转换过程中,使用两个栈,一个用于存储操作数,另一个用于存储运算符。
求值过程中,根据后缀表达式的特点,从左到右依次处理操作数和运算符,进行相应的计算。
四、实验步骤1、定义数据结构定义栈类,用于存储操作数和运算符。
定义一个结构体来表示操作数和运算符。
2、中缀表达式转后缀表达式从左到右扫描中缀表达式。
遇到操作数,直接输出。
遇到运算符,根据其优先级与栈顶运算符的优先级进行比较,决定入栈或出栈操作。
3、后缀表达式求值从左到右扫描后缀表达式。
遇到操作数,入栈。
遇到运算符,从栈中取出两个操作数进行计算,将结果入栈。
4、主函数输入中缀表达式。
调用转换函数和求值函数,输出计算结果。
五、实验代码```cppinclude <iostream>include <stack>include <string>//定义操作符的优先级int priority(char op) {if (op =='+'|| op =='')return 1;if (op ==''|| op =='/')return 2;return 0;}//中缀表达式转后缀表达式std::string infixToPostfix(std::string infix) {std::stack<char> opStack;std::string postfix ="";for (char c : infix) {if (isdigit(c)){postfix += c;} else if (c =='('){} else if (c ==')'){while (!opStackempty()&& opStacktop()!='('){postfix += opStacktop();opStackpop();}opStackpop();//弹出'('} else {while (!opStackempty()&& priority(opStacktop())>=priority(c)){postfix += opStacktop();opStackpop();}opStackpush(c);}}while (!opStackempty()){postfix += opStacktop();}return postfix;}//后缀表达式求值int evaluatePostfix(std::string postfix) {std::stack<int> operandStack;for (char c : postfix) {if (isdigit(c)){operandStackpush(c '0');} else {int operand2 = operandStacktop();operandStackpop();int operand1 = operandStacktop();operandStackpop();switch (c) {case '+':operandStackpush(operand1 + operand2);break;case '':operandStackpush(operand1 operand2);break;case '':operandStackpush(operand1 operand2);break;case '/':operandStackpush(operand1 / operand2);break;}}}return operandStacktop();}int main(){std::string infixExpression;std::cout <<"请输入中缀表达式: ";std::cin >> infixExpression;std::string postfixExpression = infixToPostfix(infixExpression);int result = evaluatePostfix(postfixExpression);std::cout <<"表达式的计算结果为: "<< result << std::endl;return 0;}```六、实验结果输入不同的中缀表达式,如“2 +3 4”“( 2 + 3 )4”等,程序能够正确地将其转换为后缀表达式,并计算出结果。
目录一.概述 (2)二.总体方案设计 (2)三.详细设计 (4)四.程序的调试与运行结果说明 (6)五.课程设计总结 (6)错误!未定义书签。
参考文献附录 (8)概述一、课程设计的目的与要求本课程设计是为了配合《数据结构》课程的开设,通过设计一个完整的程序,使学生掌握数据结构的应用,算法的编写,类C 语言的算法转换成C 程序并用Turbo C2.0 或Visual C++6.0 上机调试的基本方法。
要求如下:1. 要充分认识课程设计对自己的重要性,认真做好课程设计前的各项准备工作。
2. 既要虚心接受老师的指导,又要充分发挥主观能动性.结合课题, 独立思考,努力钻研,勤于实践,勇于创新。
3. 独立按时完成规定的工作任务,不得弄虚作假,不准抄袭他人内容,否则成绩以不及格计。
4. 课程设计期间,无故缺席按旷课处理;缺席时间达四分之一以上者,其成绩按不及格处理。
5. 在设计过程中,要严格要求自己,树立严肃,严密,严谨的科学态度, 必须按时,按质,按量完成课程设计。
6. 小组成员之间,分工明确,但要保持联系畅通,密切合作,培养良好的互相帮助和团队协作精神。
二、需求分析本课程设计的课题为表达式求值,要求:1. 用户将表达式原样输入(在表达式结尾加上#),能得出结果(为减小难度,运算结果的10 进制形式的值,不超过longdouble 的存储范围);2. 输入的数可以为小数(为减小难度,小数的整数与小数部分均不超过10 位),负数(如果负数前有运算符,则应将负数括起来),以及2进制,8进制,10 进制,16进制的数(为减小难度,数出的结果都以10 进制形式表示);3. 运算符号包括()、+、—、* 、/;括号可以多重;二总体方案设计1. 使用双链表的数据结构表示数据的存储,将用户输入的表达式以字符形式存入双链表中。
2. 对以负数开头、以括号开头、左括号后紧跟负数的特殊情况作处理。
3. 将数与运算符分开;4. ........................................................................................ 依次找到表达式最内层括号,次内层括号............... 每次找到括号内的表达式,便将其进行只有加减乘除运算的计算。
数据结构(C语言版)课程设计报告表达式求值说明书XX大学数据结构课程设计说明书题目:表达式求值院系:计算机科学与工程学院专业班级:计算机班学号:学生姓名:指导教师:2021年X月X日XX大学课程设计(论文)任务书计算机科学与工程学院学号学生姓名专业(班级)设计题目表达式求值设计技术参数系统平台:Windows7/WindowsXP开发工具:VC++6.0设计要求(1)能够计算的运算符包括:加、减、乘、除、圆括号。
(2)能够计算的数要求在实数范围内。
(3)能执行多重括号嵌套运算。
(4)对于异常表达式给出错误提示。
工作量课程设计报告要求不少于3000字。
源程序要求不少于300行工作计划2021.11.21-12.01根据课程设计大纲的要求,查找相关资料,完成需求分析;2021.12.02-12.16进行系统的概要设计;2021.12.17-12.31进行系统的详细设计和源代码的书写;2021.01.01-01.17对系统进行调试分析,写出课程设计报告。
参考资料[1]何钦铭主编.C语言程序设计.北京:高等教育出版社,2021.[2]谭浩强编著.C程序设计(第四版).北京:清华大学出版社,2021.[3]严蔚敏,吴伟民编著.数据结构(C语言版)北京:清华大学出版社,2021.[4]严蔚敏,吴伟民编著.数据结构题集北京:清华大学出版社,2021.指导教师签字教研室主任签字2021年X月X日学生姓名:学号:专业班级:课程设计题目:表达式求值指导教师评语:成绩:指导教师:年月日XX大学课程设计(论文)成绩评定表目录1需求分析12概要设计12.1设计思路12.2存储结构设计12.3功能模块设计13详细设计14运行与测试15总结1参考文献2(要求:给出一级目录和二级目录,宋体,四号字,1.5倍行距,页码使用罗马数字,居中)(报告正文部分):(要求:正文部分一律用小四号字,宋体,行距20磅。
一级标题靠左,加粗。
二级大标题靠左,不加粗。
数据结构课程设计报告(二)表达式求值(计算器).课程设计报告课程名称:数据结构课程设计设计题目:表达式求值(计算器)学院:信息科学与工程学院专业:计算机科学与技术(软件外包)姓名:指导教师:二零一五年十二月二十九日word教育资料.一、设计内容与要求1、问题描述设计一个算术计算器,能运算包括四则运算、括号的表达式的运算。
2、设计要求实现()、+、- 数据结构课程设计设计题目:表达式求值(计算器)学院:信息科学与工程学院专业:计算机科学与技术(软件外包)姓名:指导教师:二零一五年十二月二十九日word教育资料.一、设计内容与要求1、问题描述设计一个算术计算器,能运算包括四则运算、括号的表达式的运算。
2、设计要求实现()、+、:\n"); scanf("%s",data); Len=strlen(data); numb[0]=0; for(i=0;i20;i++) zhan[i].data[0]='\0'; for(i=0;i='0'data[i]='9'); else if(data[i]=='.'); else { printf("格式错误,请重新输入:\n"); szys(mark); break; } } printf("%lf\n",ns[0]);}int main (){ yxj mark[9]; mark[0].operat='#'; mark[0].rank=-1; mark[1].operat='+'; mark[1].rank=1; mark[2].operat='-'; mark[2].rank=1; mark[3].operat='*'; mark[3].rank=2; mark[4].operat='/'; mark[4].rank=2; mark[5].operat='('; mark[5].rank=-1; mark[6].operat=')'; mark[6].rank=-1; mark[7].opera该选项\n"); }}四、运行测试1.正常四则运算2.乘方运算3.除数为零时4.格式出现错误5.小数运算五、结论这次课程设计让我们更加了解大一学到的C和这个学期学到的数据结构。
数据结构课程设计表达式求值实验报告实验课程名称专业班级学生姓名学号指导教师20 至 20 年第学期第至周算术表示式求值演示一、概述数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
在这次的课程设计中我选择的题目是算术表示式求值演示。
表示式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个程序,演示用算符优先法对算术表示式求值的过程。
深入了解栈和队列的特性,以便在解决实际问题中灵活运用它们,同时加深对这种结构的理解和认识。
二、系统分析1.以字符列的形式从终端输入语法正确的、不含变量的整数表示式。
利用已知的算符优先关系,实现对算术四则混合运算表示式的求值,并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
2.一般来说,计算机解决一个具体问题时,需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型,然后设计一个解决此数学模型的算法,最后编出程序,进行测试,调试直至得到想要的答案。
对于算术表示式这个程序,主要利用栈,把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法,能够使用两个栈,一个用以寄存运算符,另一个用以寄存操作数和运算结果。
3.演示程序是以用户于计算机的对话方式执行,这需要一个模块来完成使用者与计算机语言的转化。
4.程序执行时的命令:本程序为了使用具体,采用菜单式的方式来完成程序的演示,几乎不用输入什么特殊的命令,只需按提示输入表示式即可。
(要注意输入时格式,否者可能会引起一些错误)5. 测试数据。
三、概要设计一个算术表示式中除了括号、界限符外,还包括运算数据和运算符。
由于运算符有优先级别之差,因此一个表示式的运算不可能总是从左至右的循序执行。
每次操作的数据或运算符都是最近输入的,这与栈的特性相吻合,故本课程设计借助栈来实现按运算符的优先级完成表示式的求值计算。
数据结构课程设计院别计算机与通信工程学院专业计算机科学与技术班级学号姓名指导教师成绩2013 年7 月18 日目录一、设计课题 (3)二、需求分析 (3)三、算法设计 (3)四、调试分析 (9)五、用户手册 (10)六、测试结果 (10)七、附录(源代码) (13)八、参考文献 (21)一、设计课题: 表达式求值 二、需求分析:当用户输入一个合法的算术表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号;能够计算的操作数要求在实数范围内;对于异常表达式能给出错误提示。
三、算法设计:概要说明:为实现上述程序功能,1. 首先置操作数栈为空栈,表达式起始符#为运算符栈的栈底元素;2. 依次扫描表达式中每个字符,若是操作数则进OPND 栈;若是运算符,则和OPTR 栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。
3. 先做一个适合个位的+-*/运算, 其次就要考虑到对n 位和小数点的运算。
模块间调用关系:调用主程序模块————>输出模块详细说明(ADT 描述) :ADT SqStack{数据对象:D={i a |i a ∈ElemSet,i=1,2,…,n, n ≧0} 数据对象:R1={<1,-i i a a >|1-i a ,D a i ∈,i=2,…,n}约定n a 端为栈顶,i a 端为栈底。
基本操作:InitStack(&S)操作结果:构造一个空栈S 。
GetTop(S)初始条件:栈S 已存在。
操作结果:用P 返回S 的栈顶元素。
Push(&S ,e)初始条件:栈S 已存在。
操作结果:插入元素ch 为新的栈顶元素。
Pop(&S ,e)初始条件:栈S 已存在。
操作结果:删除S 的栈顶元素。
In(c)操作结果:判断字符是否是运算符,运算符即返回1。
Precede(c1, c2)初始条件:c1,c2为运算符。
操作结果:判断运算符优先权,返回优先权高的。
Operate(a,op,b)初始条件:a,b为整数,op为运算符。
操作结果:a与b进行运算,op为运算符,返回其值。
EvaluateExpression()初始条件:输入表达式合法。
操作结果:返回表达式的最终结果。
}ADT Stack流程图及主要函数模块说明:1.数据类型:typedef struct{ double *base;double *top;int stacksize;}SqStack1;typedef struct{ char *base;char *top;int stacksize;}SqStack2;2. Precede(char c1,char c2) 判断运算符优先权,返回优先权高的。
算符间的优先关系如下:算法伪代码如下:char Precede(char c1,char c2){static char array[49]={'>', '>', '<', '<', '<', '>', '>','>', '>', '<', '<', '<', '>', '>','>', '>', '>', '>', '<', '>', '>','>', '>', '>', '>', '<', '>', '>','<', '<', '<', '<', '<', '=', '!','>', '>', '>', '>', '!', '>', '>','<', '<', '<', '<', '<', '!', '='}; //用一维数组存储49种情况switch(c1){/* i为下面array的横标 */case '+' : i=0;break;case '-' : i=1;break;case '*' : i=2;break;case '/' : i=3;break;case '(' : i=4;break;case ')' : i=5;break;case '#' : i=6;break;}switch(c2){/* j为下面array的纵标 */case '+' : j=0;break;case '-' : j=1;break;case '*' : j=2;break;case '/' : j=3;break;case '(' : j=4;break;case ')' : j=5;break;case '#' : j=6;break;}return (array[7*i+j]); /* 返回运算符array[7*i+j]为对应的c1,c2优先关系*/ }3. int EvaluateExpression()主要操作函数。
算法概要流程图:利用该算法对算术表达式3*(7-2)求值操作过程如下:步骤OPTR栈OPND栈输入字符主要操作1 # 3*(7-2)# Push(OPND,’3’)2 #3 *(7-2)# Push(OPTR,’*’)3 #* 3 (7-2)# Push(OPNR,’(’)4 #*( 3 7-2)# Push(OPND,’7’)5 #*( 3 7 -2)# Push(OPNR,’-’)6 #*(- 37 2)# Push(OPND,’2’)7 #*(- 3 7 2 )# Operate(‘7’,’-’,’2’)8 #*( 3 5 )# Pop(OPTR)9 #* 3 5 # Operate(‘3’,’*’,5’)10 # 15 # Return(GetTop2(OPND))表2算法伪代码如下:Status EvaluateExpression(){//算术表达式求值的算符优先算法。
设OPTR和OPND分别为运算符栈和运算数栈,//OP为运算符集合SqStack1 OPND;SqStack2 OPTR;char c,x,theta,y,d;double a=0,b=0,k=0,z=0;InitStack1(OPND);InitStack2(OPTR);Push2(OPTR,'#');cout<<"请输入您要求解的表达式并以“#”结尾:"<<endl;y=GetTop2(OPTR);c=getchar(); //printf("字符是%c\n",c);while (c!='#'||GetTop2(OPTR)!='#'){if(!In(c)){double d1=0,d2=1,e=0;// cout<<"kitty";// DealReal(OPND,c);d1=0;while(c>='0'&&c<='9'){c-='0';d1=d1*10+c;e=d1;c=getchar();}//whileif(c=='.'){c=getchar();while(c>='0'&&c<='9'){d2/=10;c-='0';e+=d2*c;c=getchar();}//while}//if//cout<<"chuliwan=="<<d1<<endl;Push1(OPND,e);// c=getchar();//printf("字符是%c\n",c);}else{y=GetTop2(OPTR);//cout<<y<<endl;d=Precede(y,c);//cout<<"this is"<<y<<" "<<d;switch(d){case'<'://栈顶元素优先权低Push2(OPTR,c);c=getchar();break;case'='://脱括号并接收下一字符Pop2(OPTR,x);c=getchar();break;case'>'://退栈并将运算结果入栈// cout<<"world"<<endl;Pop2(OPTR,theta);Pop1(OPND,b);//cout<<b<<endl;Pop1(OPND,a);Push1(OPND,Operate(a,theta,b));break;case'!':cout<<"请输入正确的表达式:"<<endl;break;}//switch}}//whileGetTop1(OPND,k);cout<<"表达式结果为: "<<k<<endl;return OK;}//EvaluateExpression4. Operate为进行二元运算aθb的函数,如果是编译表达式,则产生这个运算的一组相应指令并返回存放结果的中间变量名;如果是解释执行表达式,则直接进行该运算,并返回运算的结果。