算术表达式的求解-数据结构课程设计报告
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系pb0920603姓学邮名:李维谷号:pb09206285箱:指导教师:贾伯琪实验时间:20XX年10月10日一、需要分析问题描述:表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。
设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。
问题分析:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。
在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。
在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。
算法规定:输入形式:一个(:数据结构表达式求值实验报告)算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。
输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。
程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。
测试数据:正确输入:12*(3.6/3+4^2-1)#输出结果:194.4无定义运算:12*(3.6/(2^2-4)+1)#输出结果:表达式出错,除数为0,无意义错误输入:12+s#输出结果:eRRoR!二、概要设计拟采用两种类型的展分别对操作数和操作符进行操作。
算术表达式的求解-数据结构课程设计报告
算术表达式的求解-数据结构课程设计报告课程设计报告题目:算术表达式求值一、需求分析 1、设计要求:给定一个算术表达式,通过程序求出最后的结果 1>、从键盘输入要求解的算术表达式; 2>、采用栈结构进行算术表达式的求解过程; 3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果; 2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。
在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
二、概要设计1、本程序包含的模块:栈模块——实现栈抽象数据类型运算模块——实现数据表达式的运算主程序模块算术运算式的求解栈模块主函数模块main 运算模块定义栈结构初始化栈出栈入栈取栈顶元素判断输入字符类型判断符号优先级基础运算函数运算函数三、详细设计栈模块1、定义栈结构 struct Sqstack{elemtype *top;//栈顶元素 elemtype *base; //栈底元素 int stacksize;//栈的大小 };2、栈的基本操作①初始化栈status initstack(struct Sqstack &s) {=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!) return OVERFLOW; =;=stack_size; return OK; } ②入栈status push(struct Sqstack &s,elemtype e) {if(>=) {=(elemtype*)realloc(,(+stack_increasement)*sizeof(elemtype));if(! ) return OVERFLOW; =+; +=stack_increasement; } * ++=e; return OK; } ③出栈elemtype pop(struct Sqstack &s) {elemtype e; if(= =) return ERROR; e=*--;return e; }④取栈顶元素elemtype gettop(struct Sqstack &s) {elemtype e; if(==) return ERROR; e=* ; return e; } 运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0 int In(int c) {char p[10]=\ int i=0;while(p[i]!='\\0') {if(p[i]==c) return 1;i++; } return 0; }2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘'; break; case '+': case '-':if(top=='#'||top=='(')result=''; break; case '*': case '/':if(top=='*'||top=='/'||top=='^') result='>'; elseresult=''; elseresult=''; break;case '(': result='': theta=pop(optr); b=pop(opnd); a=pop(opnd); push(opnd,operate(a,theta,b)); break;// 若当前操作符的优先级低于操作符栈的栈顶元素,则将操作符栈栈顶元素出栈,并将操作数栈的栈顶两个元素出栈,计算两个元素间以操作符栈栈顶元素为运算符的数学运算}//switch }//if}//whilereturn pop(opnd); }主程序模块1、main函数void main(int argc,char *argv) {struct Sqstack opnd; //操作数栈 struct Sqstack optr;//操作符栈initstack(opdn); initstack(optr); elemtype result;printf(\ printf(\算术运算式的求解\printf(\ printf(\请输入算术运算表达式(以'#'结尾):\\n\ printf(\result=evaluate(opnd,optr);printf(\printf(\运算的结果是 :\\n \\n%d\\n\printf(\}四、调试分析 1、测试结果1> 测试数据:3+7*2-1# 测试结果:2> 测试数据:(3+7)*2-1# 测试结果:3> 测试数据: 1/0# 测试结果:2、程序时间复杂度为O;3、设计中出现的问题:在开始的设计中没有注意除数不能为0 ,后来加入if(b==0) {printf(\分母为0,the result is error\\n\ result=0; } elseresult=a/b;break;来判断除数是否为0 4、算法改进:1>输入的操作数和操作码于是字符串类型的,在原设计中实现的操作都是对个位数实现的,实用性不大,故在后来的设计中,通过一个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算2>开始只实现了加、减、乘、除及带小括号的数学运算,考虑到实用性,在后来的设计中引入pow函数,实现了乘方的运算,调整结果如下:3>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。
算术表达式的求解-数据结构课程设计报告
算术表达式的求解-数据结构课程设计报告数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用数据结构课程设计目录一、需求分析1、设计要求:本程序需要实现对算术表达式的求解功能,可以支持基本的四则运算,包括加、减、乘、除,同时还需要支持括号的使用。
2、设计构想:我们将使用栈来实现算术表达式的求解。
具体地,我们将把中缀表达式转换为后缀表达式,然后再利用栈来求解后缀表达式。
二、概要设计1、本程序包含的模块:本程序包含两个模块:中缀表达式转后缀表达式模块和后缀表达式求解模块。
三、详细设计1、定义栈结构我们定义一个栈结构,用来存储算术表达式中的运算符和操作数。
具体地,栈中的每个元素都包含两个属性:元素的值和元素的类型。
元素的值可以是一个数字或一个运算符,元素的类型可以是数字或运算符。
我们使用一个数组来实现栈的结构。
为了方便起见,我们还需要定义一些基本的栈操作,如入栈、出栈、判断栈是否为空等。
2、栈的基本操作栈是一种常见的数据结构,具有后进先出(LIFO)的特点。
栈的基本操作包括初始化栈、入栈、出栈、取栈顶元素和运算模块。
1) 初始化栈初始化栈是指将栈的各项属性设置为初始状态。
通常包括将栈顶指针设为-1,表示栈为空。
2) 入栈入栈是指将元素压入栈顶。
入栈操作需要将栈顶指针加1,并将元素存入栈顶位置。
3) 出栈出栈是指将栈顶元素弹出。
出栈操作需要将栈顶元素取出,并将栈顶指针减1.4) 取栈顶元素取栈顶元素是指获取栈顶元素的值,但不将其弹出。
取栈顶元素操作只需要返回栈顶元素的值即可。
5) 运算模块栈可以用于实现各种运算,例如中缀表达式的转换和计算、括号匹配等。
运算模块需要根据具体需求进行设计和实现。
3、判断运算符的优先级在进行中缀表达式的转换和计算时,需要判断运算符的优先级。
通常采用栈来实现这一功能。
具体实现方法是将运算符入栈,当遇到新的运算符时,将其与栈顶运算符进行比较,如果新运算符的优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到新运算符可以入栈为止。
算术表达式的求解-数据结构课程设计报告
《数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用目录一、需求分析 (3)1、设计要求: (3)2、设计构想: (3)二、概要设计 (4)1、本程序包含的模块: (4)三、详细设计 (4)1、定义栈结构 (5)2、栈的基本操作 (5)(1)初始化栈 (5)(2)入栈 (5)(3)出栈 (6)(4)取栈顶元素 (6)(5)运算模块 (6)3、判断运算符的优先级 (7)4、运算函数 (8)(1) 基础运算函数: (8)(2)运算函数 (9)(3)主程序模块 (12)四、调试分析 (12)1、测试结果 (12)2、程序时间复杂度为O(n); (13)3、设计中出现的问题: (13)4、算法改进: (14)五、课程设计总结 (15)课程设计报告一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。
在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{int *top;//栈顶元素int *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作(1)初始化栈int initstack(struct Sqstack &s){s.base=(int *)malloc(stack_size*sizeof(int));if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}(2)入栈int push(struct Sqstack &s,int e){if(s.top-s.base>=s.stacksize){s.base=(int*)realloc(s.base,(s.stacksize+stack_increasement)*sizeof(int));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}(3)出栈int pop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*--s.top;return e;}(4)取栈顶元素int gettop(struct Sqstack &s){int e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(5)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}3、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回'>',前一个运算符小于当前运算符的优先级则返'<',当前一个运算符为'('当前运算符为')'时返回'=',用于去除表达式的括号。
数据结构课程设计-表达式求值【完整版】
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【实验题目及要求】[问题描述]一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
[基本要求](1)从键盘或文件读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
(3)考虑算法的健壮性,当表达式错误时,要给出错误原因的提示。
(4) 实现非整数的处理(可选功能)。
2【源代码(C语言)】#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXSIZE 20#define OK 1#define ERROR 0#define OVERLOW 0#define YES 1#define NO 0typedefstruct{char * base;char * top;int stacksize; //最大存储量}OPTR; //字符存储栈typedefstruct{float *base;float *top;int stacksize; //最大存储量}OPND; //数值存储栈int InitOptrStack(OPTR *); //字符栈初始化函数int OptrPush(OPTR *, char); //进字符栈操作int OptrPop(OPTR*, char *); //出字符栈操作int OptrEmpty(OPTR ); //判断字符栈是否为空char GetOptrTop(OPTR); //返回字符栈顶元素int InitOpndStack(OPND *); //数值栈初始化函数int OpndPush(OPND *, float); //进数值栈操作int OpndPop(OPND*, float*); //出数值栈操作int OpndEmpty(OPND ); //判断数值栈是否为空int JudgeChar(char); //判断是否为字符float GetFloat(char *); //接收一个数字char Precede(char, char); //判断优先级操作float Caculate(float,float,char);//计算数值{char ch, noMean, ci;float num, number1, number2;OPTR optr;OPND opnd;//system("color 30");InitOptrStack(&optr);InitOpndStack(&opnd);while(1){printf(" 请输入表达式以“#”开始,以“#”结束\n ");do{ch = getchar();}while(ch !='#'); //忽略前面非‘#’字符OptrPush(&optr, ch);ch = getchar();while(ch != '#' || GetOptrTop(optr) != '#'){if(!JudgeChar(ch)){ //如果输入的是数字num = GetFloat( &ch );OpndPush(&opnd, num);else{ //输入的是字符switch(Precede(GetOptrTop(optr),ch)){case'<':OptrPush(&optr,ch); //栈顶优先级低ch = getchar();break;case'=':OptrPop(&optr,&noMean); //左右括号,把左括号出栈ch = getchar ();break;case'>': //栈顶优先级高if(OpndPop(&opnd, &number2) && OpndPop(&opnd,&number1)){OptrPop(&optr, &ci);num = Caculate(number1, number2, ci ); //出栈计算OpndPush(&opnd, num);}else{printf(" 输入过多运算符!\n");system ("PAUSE");exit(0);}break;}//witch}//else}if(opnd.top -opnd.base >= 2){printf(" 俩个括号之间缺少运算符!\n ");system ("PAUSE");exit( 0 );}OpndPop(&opnd,&num); //直接把OPND的栈元素赋值给numprintf(" 运算结果为%.3f\n", num);}system ("PAUSE");}int InitOptrStack(OPTR * OP){OP->base = (char*)malloc((MAXSIZE+1)*sizeof(char));OP->top = OP->base;OP->stacksize = MAXSIZE;return OK;}int OptrPush(OPTR *OP, char ch){*(OP->top) = ch;OP->top++;return OK;}int OptrPop(OPTR *OP, char *ch){if(OP->base == OP->top)return ERROR;else{OP->top--;*ch = *(OP->top);return OK;}}int OptrEmpty(OPTR OP){if(OP.top == OP.base )return YES;elsereturn NO;}char GetOptrTop(OPTR OP){return *(OP.top -1);}int InitOpndStack(OPND * OP){if(!(OP->base = (float*)malloc((MAXSIZE+1)*sizeof(float)))) exit(OVERLOW);OP->top = OP->base;OP->stacksize = MAXSIZE;return OK;}int OpndPush(OPND *OP, float number) {*(OP->top) = number;OP->top++;return OK;}int OpndPop(OPND *OP, float* number) {if(OP->top == OP->base)return ERROR;else{OP->top--;*number = *(OP->top);return OK;}}int OpndEmpty(OPND OP){if(OP.top == OP.base )return YES;elsereturn NO;}int JudgeChar(char ch){if(ch>='0'&&ch<= '9')return NO;elsereturn YES;}float GetFloat(char* ch){int i;float num = 0;for( i = 0; *ch>= '0'&& *ch<= '9'; i++){ num = num*10 + *ch - '0';*ch = getchar();}return num;}char Precede(char a, char b){char ch;switch(a){case'+':case'-': if(b == '*' || b == '/' || b == '(')ch = '<';elsech = '>';break;case'*':case'/': if( b == '(')ch = '<';elsech = '>';break;case'(': if(b == ')')ch = '=';elseif(b == '#'){printf(" 缺少反括号\n");system ("PAUSE");exit(0);}elsech = '<';break;case')': if(b == '('){printf(" 两个括号之间没有符号相连!\n");system("PAUSE");exit(0);}ch = '>';break;case'#': if(b == '#')ch = '=';elseif(b == ')'){printf(" 没有左括号!\n ");system("PAUSE");exit(0);}elsech = '<';break;default: printf(" 输入运算符超出范围! \n ");system ("PAUSE");exit(0);break;}return ch;}float Caculate(float number1, float number2, char ci){float num;switch( ci){case'+': num = number1 + number2; break;case'-': num = number1 - number2; break;case'*': num = number1 * number2; break;case'/': num = number1 / number2; break;}return num;}3【算法思想】根据栈的原理,建立数字栈OPND和运算符号栈OPTR,对读入的字符进行判断,存入不同的栈内,每次读入一个字符就把该字符和运算符栈顶的优先级进行比较,然后选择相应的操作,这是这个程序的核心代码,如下:switch(Precede(GetOptrTop(optr),ch)){case '<':OptrPush(&optr,ch); //栈顶优先级低ch = getchar();break;case '=':OptrPop(&optr,&noMean); //左右括号,把左括号出栈ch = getchar ();break;case '>': //栈顶优先级高if(OpndPop(&opnd, &number2) && OpndPop(&opnd, &number1)){OptrPop(&optr, &ci);num = Caculate(number1, number2, ci ); //出栈计算OpndPush(&opnd, num);}else{printf(" 输入过多运算符!\n");system ("PAUSE");exit(0);}break;}//witch4【实现效果】完全可以实现题目的要求,除了下图的错误提示,本程序还可以提示的错误有:输入过多运算符,缺少反括号,两个括号之间缺少运算符相连,缺少左括号,输入的运算符超出范围等提示。
数据结构课程设计报告-中缀算术表达式求值
课程设计报告课程名称数据结构课题名称中缀算术表达式求值专业通信工程班级通信0902学号姓名指导教师2011 年07 月01 日湖南工程学院课程设计任务书课程名称数据结构课题中缀算术表达式求值专业班级通信工程0902学生姓名学号指导老师审批任务书下达日期2011 年06 月27日任务完成日期2011 年07 月01日设计要求:1. 课程设计报告规范(1)需求分析a.程序的功能。
b.输入输出的要求。
(2)概要设计a.程序由哪些模块组成以及模块之间的层次结构、各模块的调用关系;每个模块的功能。
b.课题涉及的数据结构和数据库结构;即要存储什么数据,这些数据是什么样的结构,它们之间有什么关系等。
(3)详细设计a.采用C语言定义相关的数据类型。
b.写出各模块的类C码算法。
c.画出各函数的调用关系图、主要函数的流程图。
(4)调试分析以及设计体会a.测试数据:准备典型的测试数据和测试方案,包括正确的输入及输出结果和含有错误的输入及输出结果。
b.程序调试中遇到的问题以及解决问题的方法。
c.课程设计过程经验教训、心得体会。
(5)使用说明用户使用手册:说明如何使用你编写的程序,详细列出每一步的操作步骤。
(6)书写格式a.设计报告要求用A4纸打印成册:b.一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。
(7)附录源程序清单(带注释)2. 考核方式指导老师负责验收程序的运行结果,并结合学生的工作态度、实际动手能力、创新精神和设计报告等进行综合考评,并按优秀、良好、中等、及格和不及格五个等级给出每位同学的课程设计成绩。
具体考核标准包含以下几个部分:(1)平时出勤(占10%)(2)系统需求分析、功能设计、数据结构设计及程序总体结构合理与否(占10%)(3)程序能否完整、准确地运行,个人能否独立、熟练地调试程序(占40%)(4)设计报告(占30%)注意:不得抄袭他人的报告(或给他人抄袭),一旦发现,成绩为零分。
算术表达式求值演示-课程设计报告
算术表达式求值演示目录第一章概述 (1)第二章系统分析 (1)第三章概要设计 (2)第四章详细设计 (5)第五章运行与测试 (13)第六章总结与心得 (16)参考文献 (16)第一章概述课程设计是实践性教学中的一个重要环节,它以某一课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。
课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。
《数据结构》是一门重要的专业基础课,是计算机理论和应用的核心基础课程。
数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
在这次的课程设计中我选择的题目是算术表达式求值演示。
表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个程序,演示用算符优先法对算术表达式求值的过程。
深入了解栈和队列的特性,以便在解决实际问题中灵活运用它们,同时加深对这种结构的理解和认识。
第二章系统分析1.以字符列的形式从终端输入语法正确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例子在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
2.一般来说,计算机解决一个具体问题时,需要经过几个步骤:首先要从具体问题抽象出一个适当的数学模型,然后设计一个解决此数学模型的算法,最后编出程序,进行测试,调试直至得到想要的答案。
对于算术表达式这个程序,主要利用栈,把运算的先后步骤进行分析并实现简单的运算!为实现算符优先算法,可以使用两个栈,一个用以寄存运算符,另一个用以寄存操作数和运算结果。
3.演示程序是以用户于计算机的对话方式执行,这需要一个模块来完成使用者与计算机语言的转化。
4.程序执行时的命令:本程序为了使用具体,采用菜单式的方式来完成程序的演示,几乎不用输入什么特殊的命令,只需按提示输入表达式即可。
数据结构课程设计报告(二)表达式求值(计算器)
课程设计报告课程名称:数据结构课程设计设计题目:表达式求值(计算器)学院:信息科学与工程学院专业:计算机科学与技术(软件外包)姓名:指导教师:二零一五年十二月二十九日一、设计容与要求1、问题描述设计一个算术计算器,能运算包括四则运算、括号的表达式的运算。
2、设计要求实现()、+、-、*、/、^ 等运算,实现小数和整数混合运算,优先级的处理,能判断算术表达式是否正确等。
二、算法设计1、输入并建立表达式,运用数组结构体构建将整型数字与操作符结合定义运算符的优先级。
typedef struct yxj{char operat;int rank;}yxj;2、分别建立一个操作数栈和操作符栈存放数字和操作符,定义操作符栈第一个元素优先级最低。
3、自左向右扫描字符串遇到字符串中的数字时一律提取转换成double型存入操作数栈。
遇到操作符时,则将当前运算符的优先级数与运算符栈顶元素的优先级数相比较。
若当前运算符的优先级数大,则进栈;反之,则取出栈顶的运算符,并在数栈中连续取出两个栈顶元素作为运算对象进行运算,并将运算结果存入数栈,然后继续比较当前运算符与栈顶元素的优先级。
直到当前运算符进栈。
4、对比运算符进行+ - * /()^ 运算。
三、程序代码#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define N 100typedef struct yxj{char operat;int rank;}yxj;typedef struct str{char data[N];}zs;void szys(yxj mark[]){yxj os[N];char ch;double ns[N];zs zhan[20];int numb[N];int Len,p=0,q=1,i,o=1,n=0;char data[N];os[0]=mark[0];printf("请输入算术(+ - * / ^)表达式(以 = 结束):\n");scanf("%s",data);Len=strlen(data);numb[0]=0;for(i=0;i<20;i++)zhan[i].data[0]='\0';for(i=0;i<Len;i++){int t=0;if(data[i]=='^'||data[i]=='+'||data[i]=='-'||data[i]=='*'||data[i]=='/'||data[ i]=='('||data[i]==')'||data[i]=='='){int j,k=0;if((data[i]=='='||data[i]=='^'||data[i]=='+'||data[i]=='-'||data[i]=='*'||data [i]=='/')&&(data[i-1]=='^'||data[i-1]=='+'||data[i-1]=='-'||data[i-1]=='*'||data[i -1]=='/')){printf("格式错误\n");return;}numb[q++]=i;while(zhan[(p+k)/2].data[0]!='\0'){k++;}for(j=numb[q-2];j<numb[q-1];j++)if(data[j]>='0'&&data[j]<='9'||data[j]=='.')zhan[(p+k)/2].data[t++]=data[j];zhan[(p+k)/2].data[t]='\0';if(zhan[(p+k)/2].data[0]!='\0')ns[n++]=atof(zhan[(p+k)/2].data);p++;for(j=0;j<8;j++)if(mark[j].operat==data[i])break;while(1){if(mark[j].operat=='('){os[o++]=mark[j];break;}else if(mark[j].rank>os[o-1].rank&&mark[j].operat!='(') {os[o++]=mark[j];break;}else{double numb1,numb2,numb;ch=os[--o].operat;if(ch=='+'){numb1=ns[--n];numb2=ns[--n];numb=numb1+numb2;ns[n++]=numb;}if(ch=='-'){numb1=ns[--n];numb2=ns[--n];numb=numb2-numb1;ns[n++]=numb;}if(ch=='*'){numb1=ns[--n];numb2=ns[--n];numb=numb2*numb1;ns[n++]=numb;}if(ch=='/'){numb1=ns[--n];numb2=ns[--n];if(numb1==0){printf("无效操作\n");return;}else{numb=numb2/numb1;ns[n++]=numb;}}if(ch=='^'){numb1=ns[--n];numb2=ns[--n];numb=pow(numb2,numb1);ns[n++]=numb;}}}}else if(data[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].operat='=';mark[7].rank=0;mark[8].operat='^';mark[8].rank=3;while(1){char i[N];printf("*****1、计算器*****\n");printf("*****0、退出 *****\n");scanf("%s",&i);if(strcmp(i,"0")==0)break;else if(strcmp(i,"1")==0)szys(mark);elseprintf("没有该选项\n");}}四、运行测试1.正常四则运算2.乘方运算3.除数为零时4.格式出现错误5.小数运算五、结论这次课程设计让我们更加了解大一学到的C和这个学期学到的数据结构。
算术表达式求值问题z-数据结构与算法课程设计报告
合肥学院计算机科学与技术系课程设计报告2009~2010学年第二学期课程数据结构与算法课程设计名称算术表达式求值问题学生姓名杨松学号0804012031专业班级08计科(2)指导教师王昆仑张贯虹2010年6月题目:(算术表达式求值问题)一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正整数,运算符只含加减乘除四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
要求:(1)从键盘读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
选作内容:操作数类型扩充到实数。
一、问题分析和任务定义要对一个含有加减乘除四则运算的合法的算术表达式进行求值,①首先,应了解算术表达式的四则运算的规则:(1)从左向右计算(2)先乘除,后加减(3)先括号内,后括号外由此可知,比如算术表达式(7+15)*(23-28/4)的计算顺序,即为(7+15)*(23-28/4)=22*(23-28/4)=22*(23-7)=22*16=352②其次,应明确“算符优先法”的内容:算符优先法就是根据上述四则运算规则确定的优先关系来实现对表达式的编译或解释执行的。
一个简单的四则运算表达式由操作数(operand)、运算符(operator)和界限符(delimiter)组成,其中操作数是正整数,运算符只含加、减、乘、除四种,界限符有左右括号和表达式起始、结束符“#”;而且,为了统一算法的描述,将运算符和界限符通称为算符。
算符集OP={+,-,*,/,(,),#}。
根据上述3条运算规则,在具体的运算的每一步中,任意两个相继出现的算符θ1和θ2之间的优先关系只能是如下3中关系之一:θ1<θ2θ1的优先级低于θ2θ1=θ2θ1的优先级等于θ2θ1>θ2θ1的优先级高于θ2下表定义了算符之间的这种优先关系。
算术表达式求值数据结构实验报告
算法的正确性和效率分析
正确性
所有实现的数据结构都正确地实现了算术表达式求值的功能,没有出现计算错 误的情况。
效率
在处理大量数据时,使用堆栈(Stack)和队列(Queue)的数据结构表现最 佳。堆栈在处理后缀表达式时效率最高,而队列在处理中缀表达式时效率最高 。
数据结构优化的效果评估
使用哈希表(Hash Table)
展望未来,希望能够进一步研究算术 表达式求值算法的优化和改进,提高 计算效率和精度。
THANKS
感谢观看
05
列表(List)
数组(Array) 元组(Tuple) 集合(Set)
字典( Dictiona…
由于列表在Python中是动 态数组,其性能在处理大 量数据时相对较差。在算 术表达式求值中,列表的 平均执行时间最长。
使用NumPy库的数组结构 ,其性能在处理大量数据 时优于列表。但在算术表 达式求值中,其性能仍然 不如其他数据结构。
03
了解如何使用栈数据结构实现括号匹配和回退机制 。
掌握数据结构在算术表达式求值中的应用
01 熟悉使用数组、链表等基本数据结构存储和操作 算术表达式。
02 掌握如何使用树形数据结构表示算术表达式,如 二叉树或表达式树。
03 了解动态规划在优化算术表达式求值中的运用。
提高编程能力和解决问题的能力
01
在处理重复元素时,使用哈希表可以显著提高数据结构的效率。在算术表达式求值中,哈希表的使用可以减少重 复计算和查找的时间。
预处理输入数据
对输入的算术表达式进行预处理,如括号消除、指数化等,也可以提高数据结构的效率。预处理可以减少运算的 复杂度和时间。
05
实验总结
本次实验的收获和体会
C语言_算数表达式求值_课程设计报告
目录一.概述 (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. ........................................................................................ 依次找到表达式最内层括号,次内层括号............... 每次找到括号内的表达式,便将其进行只有加减乘除运算的计算。
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级:09级材料科学与工程系pb0920603姓学邮名:李维谷号:pb09206285箱:指导教师:贾伯琪实验时间:20XX年10月10日一、需要分析问题描述:表达式计算是实现程序设计语言的基本问题之一,它的实现是栈的应用的一个典型例子。
设计一个程序,演示通过将数学表达式字符串转化为后缀表达式,并通过后缀表达式结合栈的应用实现对算术表达式进行四则混合运算。
问题分析:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因而在程序设计时,借助栈实现。
设置运算符栈(字符型)和运算数栈(浮点型)辅助分析算符优先关系。
在读入表达式的字符序列的同时完成运算符和运算数的识别处理,然后进行运算数的数值转换在进行四则运算。
在运算之后输出正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。
算法规定:输入形式:一个(:数据结构表达式求值实验报告)算术表达式,由常量、变量、运算符和括号组成(以字符串形式输入)。
为使实验更完善,允许操作数为实数,操作符为(、)、.(表示小数点)、+、-、*、/、^(表示乘方),用#表示结束。
输出形式:演示表达式运算的中间结果和整个表达式的最终结果,以浮点型输出。
程序功能:对实数内的加减乘除乘方运算能正确的运算出结果,并能正确对错误输入和无定义的运算报错,能连续测试多组数据。
测试数据:正确输入:12*(3.6/3+4^2-1)#输出结果:194.4无定义运算:12*(3.6/(2^2-4)+1)#输出结果:表达式出错,除数为0,无意义错误输入:12+s#输出结果:eRRoR!二、概要设计拟采用两种类型的展分别对操作数和操作符进行操作。
算术表达式--数据结构实验报告
实验报告课程名称:数据结构与算法课程类型:必修实验项目名称:线性表及应用实验题目:表达式中缀转后缀并求值班级:0903301学号:17姓名:李清掌握线性表的使用,能用栈将中缀表达式转换成后缀表达式并求值。
二、实验要求及实验环境实验要求:1、使用栈来进行操作2、能输出后缀表达式3、正确求出表达式的值并输出该值实验环境:NetBeans IDE / win 7系统三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系,自己扩展内容的等)主要数据类型:queue <char> A 存储原来算术表达式stack <char> B存储转换成的后缀表达式stack <char> B1 临时存储后缀表达式(B)stack <char> C 表达式转化过程使用的过度栈,存储操作符stack <int> S 存储数字(包括输入和计算过程中的数)char ch,QQint d1,d2,d3Transition函数流程图:Value函数的流程图:文档收集自网络,仅用于个人学习注:在value 函数中还可以判定除数是否为0,为0则输出"0 can'tbe a divisor!",并终止程序。
四、测试结果B 弹栈判断数字字符运算符求出其数值并存入S 栈中从S 栈中取出栈顶的两个数,进行相应的运算,并把结果存入S 中B 空返回S 的栈顶元素判断B 不空由测试结果可知,基本完成了实验要求。
五、系统不足与经验体会1、该程序只能运算整数,也不能处理输入的负数2、不能处理非法输入3、几种线性表(队列、栈、数组、链表)从根本上说可以实现同一个功能,只是难易程度的问题,熟悉各线性表的特点有助于快速选择简单的方法。
4、第一次实验,代码比较乱,可能有些重复的地方六、附录:源代码(带注释)#include<iostream>#include <string>#include <stack>#include <queue>using namespace std;void transition(queue <char> &A, stack <char> &B) //将中缀表达式转换成后缀表达式{stack <char> C; //表达式转化过程使用的过度栈char ch;while(!()){ch = (); ();if(ch >= '0' && ch <= '9') //判断数字{(ch); //压栈while(!() && () >= '0' && () <= '9'){()); //其它位依次入栈至该数字结束();}(' '); //用空格表示一个数字的结束}else if(ch == '(') (ch) ;//判断为左括号else if(ch == ')') //判断为右括号,把上一个左括号之前的所有操作符弹出存入B中,再弹出左括号{while () != '('){());();}();}else if(ch == '+' || ch == '-')//判断为加减号,把上一个左括号之前的所有操作符弹出存入B中,再把+,-存入C中{while(!() && () != '('){());();}(ch);}else if (ch == '*' || ch == '/') //判断为乘除号,弹出前面紧邻的*,/,再把这个*或/存入C中{while() == '*' || () == '/'){());();}(ch);}}while (!())//将C栈中所有运算符依次弹出存入B栈中{());();}//下面是将B倒序while(!()){());();}while(!()){());();}return ;}int value(stack <char> &B) //后缀表达式求值{int d1,d2,d3;stack <int> S;char ch;while(!()){ch = ();();if(ch >= '0'&&ch <= '9')//将数字字符转换成数字 {d1 = 0;while(ch != ' '){d1 = 10*d1 + ch - '0';//求出一个数字的数值 ch = (); ();}(d1);}else{d2 = (); ();d3 = (); ();switch(ch) //运算符操作{case'+':( d3+d2 );break;case'-':( d3-d2 );break;case'*':( d3*d2 );break;case'/':if(d2 != 0){( d3/d2 );}else //0不能做除数{cout << "0 can't be a divisor!" << endl;exit(0);}break;}}}return ();}int main(){char QQ;queue <char> A; //存储原来算术表达式stack <char> B,B1; //存储转换成的后缀表达式 cout << "Please input your expession:" << endl; while( QQ != '\n'){QQ = getchar();(QQ);};transition(A,B);//前缀表达式转换成后缀表达式cout << "The pofix expession is:" << endl;while(!()){cout << ();());();//将B栈数据转移到B1}cout << endl ;while(!())//数据返还给B{());();}cout << "Value:" << endl << value(B) << endl; return 0;}。
数据结构课程设计算术表达式求值
计算机科学系《数据结构课程设计》报告课题名称:算术表达式求值目录1.问题描述-----------------------------------------------------------32.基本要求-----------------------------------------------------------33.工具/准备工作----------------------------------------------------34.分析与实现--------------------------------------------------------45. 课程设计体会与感悟------------------------------------------161.问题描述从键盘上输入中缀算术表达式,包括括号,计算出表达式的值。
2.基本要求(1)程序能对所输入的表达式做简单的判断,如表达式有错,能给适当提示。
(2)能处理单目运算符:+,-。
3.工具/准备工作在开始项目之前,应回顾复习相关内容。
需要一台计算机装有visual C++。
4.分析与实现对于中缀表达式,一般运算规则如下:(1)先乘方,再乘除,最后加减;(2)同级运算从左算到右;(3)先括号内再括号外;(4)用到的头文件”utility.h”,”lk_stack.h”,”node.h”,”calculator.h”.根据实践经验,可以对运算符设置统一的优先级,从而方便比较。
表中给出了包括加、上面讨论的的+、—为双目运算符,如为单目运算符,编程实现时,可在前面加上0而转化为双目运算符。
如在+、—的前一个字符(如当前字符不是运算符时,规定用0表示)为‘=’或‘(’,则为单目运算符。
具体实现算法时,可设置两个工作栈,一个为操作栈,一个为操作符栈optr,另外一个为操作数栈opnd,算法基本思路如下:(1)将optr栈和opnd栈清空,在optr栈中加入一个‘=‘。
C语言_算数表达式求值_课程设计报告
特点:本程序能进行小数、以及2进制、8进制、16进制的运算。
不足:结果都以10进制形式表示,用户不能改变;结果的10进制形式不能超
出longdouble型数据能存储的数的范围;
进一步的设想:将数分段存储,内存动态分配,使其能进行天文数字运算;录入其他的运算符例如指数运算,开方运算,取余运算,解一元一次方程,解二元一次方程组。
三 详细设计
我任务是整个程序的算法设计, 以及部分子函数的编写, 经过其他组员编写的子函数的处理, 将表达式变为一个普通的表达式, 其中数与运算符已经分开,将这个表达式的头指针传递到我所编写函数
中,运算思想为:找到最内层的一对括号, 计算括号间的表达式的值,得到值之后,用这个值替换掉原始位置上的一对括号, 以及其中的表达式。例如(((6.5-2*2.25)*2-6)/2+1.5)+3#,第一次替换后为((2*2-6)/2+1.5)+3#,第二次替换后为(-2/2+1.5)+3#,第三次替换后为0.5+3#,当没有括号时调用四则运算函数直接计算。
Node *node,*head;
Node_ys_char *node_char;
switch(m)
{
case 2:
JiWei=2;
max=50;
break;
case 8:
JiWei=8;
max=56;
break;
case 10:
JiWei=10;
max=97;
break;
case 16:
JiWei=16;
p->c='+';
算术表达式求值-数据结构实验报告
//存放运算数的栈的顺序存储表示
//存放运算符的栈的顺序存储表示
void InitStack(SqStack *S) //构造空栈(运算数 栈) { S->base=(float*)malloc((STACK_INIT_SIZE)*sizeof(float)); S->top=S->base; S->stacksize=STACK_INIT_SIZE; } void initStack(sqStack *S) //构造空栈(运算符 栈) { S->base=(char*)malloc((STACK_INIT_SIZE)*sizeof(char)); S->top=S->base; S->stacksize=STACK_INIT_SIZE; } float GetTop(SqStack *S) //用e返回栈顶元素(运
初始条件:a, b为整数,OP为运算符。 操作结果:a与b进行运算,OP为二元运算符,返回其值。 }ADT Stack (2)符号之间的优先权关系比较 <:的优先权低于: =:的优先权等于 >:的优先权高于 + + * / ( ) # > > > > < > < > > > > < > < * < < > > < > < / < < > > < > < < ( < < < < < ) > > > > = > > = # > > > >
//用e返回栈顶元素
数据结构》课程设计报告-实现对算术四则溷合运算表达式的求值以及大整数计算
江汉大学文理学院课程设计报告课程名称:设计题目:系别:专业:组别:学生姓名:起止日期:年月日~年月日指导教师:承诺书本人郑重声明:本人所呈交的学术论文,是本人在导师指导下独立进行研究工作所取得的成果。
除文中已经注明引用的内容外,本论文不包括任何其他个人或集体已经发表或撰写过的作品成果。
对本文的研究作出重要贡献的个人和集体,均已在文中以明确的方式标明。
本人完全意识到本声明的法律结果由本人承担。
学生(签名):年月日《数据结构》课程设计报告题目:实现对算术四则混合运算表达式的求值以及大整数计算一.设计目的数据结构是计算机专业的核心课程,是一门实践性很强的课程。
课程设计是加强学生实践能力的一个强有力手段,要求学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并上机调试的基本方法,还要求学生在完成程序设计的同时能够写出比较规范的设计报告。
严格实施课程设计这一环节,对于学生基本程序设计素养的培养和软件工作者工作作风的训练,将起到显著的促进作用。
二.问题描述(一)当用户输入一个合法的算术表达式后,能够返回正确的结果。
能够计算的运算符包括:加、减、乘、除、括号;能够计算的操作数要求在实数范围内;对于异常表达式能给出错误提示。
(二)求两个不超过200位的非负整数的和,积和商。
三.调试与操作说明(一)需求分析本程序所做的工作为:能直接求出四则表达式的值,并输出;可以解决因数值位数太大unsigned类型都无法表示的大数之间的运算。
本程序可用于小学教师对学生作业的快速批改以及对数值位数要求较大的科学运算。
此程序规定:1.程序的主要功能包括两部分:表达式求解和大整数的运算。
2.表达式求解中输入的必需为一个正确的四则表达式,可以是整型也可以为浮点型,比如:3*(7-2)+5和3.154*(12+18)-23。
大整数的运算中根据提示要输入两行数据位数不能大于200位。
3.程序的输出:表达式求解中为一浮点型数据,大整数运算中输出的即为运算之后的结果,结果里不能有多余的前导0。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告题目:算术表达式求值一、需求分析1、设计要求:给定一个算术表达式,通过程序求出最后的结果1>、从键盘输入要求解的算术表达式;2>、采用栈结构进行算术表达式的求解过程;3>、能够判断算术表达式正确与否;4>、对于错误表达式给出提示;5>、对于正确的表达式给出最后的结果;2、设计构想:为了实现算符优先算法使用两个工作栈,一个称作OPTR,以寄存运算符;另一个称作OPND,用以寄存操作数或运算结果。
在操作数和操作符入栈前,通过一个函数来判别,输入的是操作数还是操作符,操作数入OPND,操作符入OPTR。
在输入表达式的最后输入‘#’,设定‘#’的优先级最低,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈,遇到运算符则与栈顶运算符比较优先级,若当前运算符优先级高,则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
二、概要设计1、本程序包含的模块:(1)栈模块——实现栈抽象数据类型(2)运算模块——实现数据表达式的运算(3)主程序模块三、详细设计(1)栈模块1、定义栈结构struct Sqstack{elemtype *top;//栈顶元素elemtype *base; //栈底元素int stacksize;//栈的大小};2、栈的基本操作①初始化栈status initstack(struct Sqstack &s){s.base=(elemtype *)malloc(stack_size*sizeof(elemtype)); if(!s.base)return OVERFLOW;s.top=s.base;s.stacksize=stack_size;return OK;}②入栈status push(struct Sqstack &s,elemtype e){if(s.top-s.base>=s.stacksize){s.base=(elemtype*)realloc(s.base,(s.stacksize+stack_increase ment)*sizeof(elemtype));if(!(s.base))return OVERFLOW;s.top=s.base+s.stacksize;s.stacksize+=stack_increasement;}* s.top++=e;return OK;}③出栈elemtype pop(struct Sqstack &s){elemtype e;if(s.top= =s.base)return ERROR;e=*--s.top;return e;}④取栈顶元素elemtype gettop(struct Sqstack &s){elemtype e;if(s.top==s.base)return ERROR;e=*(s.top-1);return e;}(2)运算模块1、判断输入字符c是否为操作符:若是,则返回1;否则,返回0int In(int c){char p[10]="+-*/()#^";int i=0;while(p[i]!='\0'){if(p[i]==c)return 1;i++;}return 0;}2、判断运算符的优先级char precede(char top,char c)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘<’,当前一个运算符为‘(’当前运算符为‘)’时返回‘=’,用于去除表达式的括号。
{char result;switch(c){case '#': result='>'; break;case '+':case '-':if(top=='#'||top=='(')result='<';elseresult='>'; break;case '*':case '/':if(top=='*'||top=='/'||top=='^')result='>';elseresult='<'; break;case '%':if(top=='%'||top=='/'||top=='^'||top=='*')result='>';elseresult='<';break;case ')':if(top=='(')result='=';elseresult='>'; break;case '(': result='<'; break;case '^': result='<'; break;default: printf("操作符输入错误!\n");}return result;}3、运算函数①基础运算函数:实现相应的加、减、乘、除、乘方及带小括号的基本数学运算并返回结果,其中a,b为两个操作数,theta为操作符elemtype operate(elemtype a,char theta,elemtype b){elemtype result;switch(theta){case '+': result=a+b; break;case '-': result=a-b; break;case '*': result=a*b; break;case '/':if(b==0){printf("\n\n输入错误!分母不能为0!\n");result=0;}elseresult=a/b;break;case '%':if(b==0||b==NULL){printf("\n\n输入错误!\n");return 0;break;}elseresult=a%b;break;case '^': result=(int)pow((double)a,(double)b); break; default: printf("操作符输入错误!\n");}return result;}②运算函数elemtype evaluate(struct Sqstack opnd,struct Sqstack optr)//该函数为求表达式的值的整个操作过程,通过调用相应的函数实现遇到运算符则与栈顶运算符比较优先级,//若当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,同时两操作数出栈,进行运算,所得结果入数栈, //重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
//若操作数为个位数,则直接将输入的字符减48后入栈,若为多位数,则通过flag来实现。
若输入字符c为操作数且flag=1(即操作数为多位数),则将操作数栈的栈顶元素出栈后乘以10,然后加上,(c-48)然后将二者的和入操作数栈。
{elemtype a,b,c,theta,e;initstack(optr);push(optr,'#');initstack(opnd);c=getchar();int flag=0;//当输入操作数时flag=1;当输入操作符时flag=0;//当前输入为操作数且flag=1时,将操作数栈的栈顶元素出栈,然后将其和当前输入转换成相应的int类型while(c!='#'||gettop(optr)!='#'){if(!In(c)) //c若为操作数则入opnd栈{if(flag==1){e=pop(opnd); // 取栈顶元素push(opnd,(e*10+(c-48)));//将输入数在转化为int型,并将上次输入数*10并与当前操作数相加,将结果如操作数栈}elsepush(opnd,c-48);flag=1;c=getchar();}{flag=0;//当前字符为操作符,则入操作符栈,并将flag置为0switch(precede(gettop(optr),c))// 判断当前操作数与操作符栈中的栈顶元素的优先级{case '<': push(optr,c); c=getchar(); break;// 若当前操作符的优先级高于操作符栈的栈顶元素,则将当前操作符入操作符栈case '=': e=pop(optr); c=getchar(); break;// 若当前操作符与操作符栈的栈顶元素构成匹配的括号,则//将操作符栈顶元素出栈case '>': theta=pop(optr); b=pop(opnd); a=pop(opnd); push(opnd,operate(a,theta,b)); break;// 若当前操作符的优先级低于操作符栈的栈顶元素,则将操作符栈栈顶元素出栈,并将操作数栈的栈顶两个元素出栈,计算两个元素间以操作符栈栈顶元素为运算符的数学运算}//switch}//ifreturn pop(opnd);}(3)主程序模块1、main函数void main(int argc,char *argv[]){struct Sqstack opnd; //操作数栈struct Sqstack optr;//操作符栈initstack(opdn);initstack(optr);elemtype result;printf("**************************************************\n");printf("算术运算式的求解");printf("\n************************************************\n");printf("\n请输入算术运算表达式(以'#'结尾):\n");printf("\n");result=evaluate(opnd,optr);printf("\n************************************************\n");printf("\n\n运算的结果是 :\n \n%d\n",result);printf("\n************************************************\n");}四、调试分析1、测试结果1> 测试数据:3+7*2-1#测试结果:2> 测试数据:(3+7)*2-1#测试结果:3> 测试数据: 1/0#测试结果:2、程序时间复杂度为O(n);3、设计中出现的问题:在开始的设计中没有注意除数不能为0 ,后来加入if(b==0){printf("分母为0,the result is error\n");result=0;}elseresult=a/b;break;来判断除数是否为04、算法改进:1>输入的操作数和操作码由于是字符串类型的,在原设计中实现的操作都是对个位数实现的,实用性不大,故在后来的设计中,通过一个标志flag实现了标志操作数的连续输入的判别,继而实现了多位数的表达式运算2>开始只实现了加、减、乘、除及带小括号的数学运算,考虑到实用性,在后来的设计中引入pow函数,实现了乘方的运算,调整结果如下:3>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。