数据结构算术表达式求值课程设计
算术表达式的求解-数据结构课程设计报告

课程设计报告题目:算术表达式求值一、需求分析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)//该函数为判断当前运算符与前一个运算符的优先级,前一个运算符高于或等于当前运算符的优先级则返回‘>’,前一个运算符小于当前运算符的优先级则返‘<’,当前一个运算符为‘(’当前运算符为‘)’时返回‘=’,用于去除表达式的括号。
数据结构——算术表达式求值算法.doc

数据结构——算术表达式求值算法.沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:算术表达式求值算法院(系):计算机学院专业:计算机科学与技术班级:学号:姓名:指导教师:丁国辉完成日期:XXXX年01月11日word教育资料.目录第1章概要设计11.1题目的内容与要求11.2总体结构1第2章详细设计32.1栈的顺序存储模块32.2进栈模块32.3出栈模块42.4运算模块42.5判断优先级模块52.6处理表达式主体模块6第3章调试分析8第4章运行结果9参考文献11附录(程序清单)12word教育资料.第1章概要设计1.1题目的内容与要求内容:设计程序,其能够求解任意给定算数表达式的值,算数表达式中的操作符来自于集合{+,-,*,\},表达式允许包括小括号“()”,表达式的输入以“#”作为结束标志。
要求:1) 利用栈结构实现表达式求值算法,即在约定的条件下,正确输入表达式,经过程序的运行之后,给出表达式的值;2) 系统利用C语言实现;3) 独立完成系统的设计、编码和调试。
1.2总体结构本程序主要分为六个模块(主要算法模块图见图1.1):栈的顺序存储模块、进栈模块、出栈模块、运算模块、判断优先级模块、处理表达式主体模块。
栈的顺序存储模块:分别建立两个栈,第一个用来存储运算符,第二个是用来存储数字。
进栈模块:运算符和数字分别存储在运算符栈和数字栈中,以便运算时的调用。
出栈模块:由于运算的需要,就必须把运算符和数字分别从运算符栈和数字栈中取出来。
运算模块:程序在遇到运算符的时候,根据此模块的要求进行运算。
判断优先级模块:找出栈顶算符和即将入栈算符的对应的下标,然后根据算符间的优先关系表判断出算符的优先关系。
处理表达式主体模块:结合运算模块和判断优先级模块,对表达式进行系统处理,求出算数表达式的值。
算术表达式求值算法出栈模块判断优先级模块处理表达式主体模块栈的顺序存储模块运算模块进栈模块图 1.1 主要算法模块图.第2章详细设计在本次课程设计中,我们用到了栈这个重要的数据结构。
算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告课程设计报告题目:算术表达式求值一、需求分析 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>最初设计的运行界面过于单调,不够友好,改进时加入一些*调整调整结果如下:五、课程设计总结本学期是我第一次接触课程设计,发现了很多学习上的问题,也有很多收获。
数据结构课程设计- 算术表达式求值

课程设计报告课程名称数据结构课程设计题目算术表达式求值指导教师设计起始日期 4.18~4.25学院计算机学院系别计算机科学与工程学生姓名班级/学号成绩一、需求分析设计一个算术表达式四则运算的程序,要求完成包括加、减、乘、除运算,包含括号的基本整数表达式的运算。
在这里运算数可以1位长度,也可以多位长度。
在运算之后输出的正确运算结果,输入表达式后演示在求值中运算数栈内的栈顶数据变化过程,最后得到运算结果。
(1)输入:3*(7-2)(2)输出:数据栈栈顶元素:3,7,2,7,5,3,15结果:15(3)自选数据二、概要设计1、使用栈的数据结构表示数据的存储。
2、设计算法将中缀表达式转换成后缀表达式,用栈的数据结构实现表达式的运算。
3、把中缀表达式转换为后缀表达式算法的基本思路是从头到尾地扫描中缀表达式中的每个字符,对于不同类型的字符按不情况进行处理。
三、详细设计数据结构:字符类型栈/* 定义字符类型栈*/typedef struct{char stackname[20];char *base;char *top;} Stack;算法:将中缀表达式转换为后缀表达式void Change(char* s1, char* s2)// 将字符串s1中的中缀表达式转换为存于字符串s2中的后缀表达式{Stack R; // 定义用于暂存运算符的栈InitStack(R); // 初始化栈Push(R,'#'); // 给栈底放入’#’字符,它具有最低优先级0int i,j;i=0; // 用于指示扫描s1串中字符的位置,初值为0j=0; // 用于指示s2串中待存字符的位置,初值为0char ch=s1[i]; // ch保存s1串中扫描到的字符,初值为第一个字符while( ch!='#'){ // 顺序处理中缀表达式中的每个字符if(ch==' ')// 对于空格字符不做任何处理,顺序读取下一个字符ch=s1[++i];else if(ch=='('){ // 对于左括号,直接进栈Push(R,ch);ch=s1[++i];}else if(ch==')'){ // 对于右括号,使括号内的仍停留在栈中的运算符依次// 出栈并写入到s2中while(Peek(R)!='(')s2[j++]=Pop(R);Pop(R); // 删除栈顶的左括号ch=s1[++i];}else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'){ // 对于四则运算符,使暂存在栈中的不低于ch优先级// 的运算符依次出栈并写入到s2中char w=Peek(R);while(Precedence(w)>=Precedence(ch)){ // Precedence(w)函数返回运算符形参的优先级s2[j++]=w;Pop(R); w=Peek(R); }}四、调试分析调试:在设计过程中出现程序不能运行,发现不能找到结束标识符,因此在设计的时候需要人为动态添加结束标识符‘#’,顺利运行算法时间和空间分析:算法的运行时间主要花在while循环上,它从头到尾扫描后缀表达式中的每一个数据(每个操作数或运算符均为一个数据),若后缀表达式由n个数据组成,则此算法的时间复杂度为O(n)。
数据结构课程设计-算术表达式求值的实现

课程设计报告课程设计名称:数据结构课程设计课程设计题目:算术表达式求值的实现院(系):*****专业:*****班级:*****学号:*****姓名:*****指导教师:*****目录1 课程设计介绍 (1)1.1课程设计内容 (1)1.2课程设计要求 (1)2 课程设计原理 (2)2.1课设题目粗略分析 (2)2.2原理图介绍 (2)2.2.1 功能模块图 (2)2.2.2 流程图分析 (3)3 数据结构分析 (5)3.1存储结构 (5)3.2算法描述 (5)4 调试与分析 (7)4.1调试过程 (7)4.2程序执行过程 (7)参考文献 (8)附录(关键部分程序清单) (9)1 课程设计介绍1.1 课程设计内容编写算法能够进行整型和实型数的表达式求值,能够根据运算的数据选择正确的运算结果的数据类型,表达式的运算符为:+,—,*,/,(,),且括号可以嵌套。
1.2 课程设计要求1.给出必要的输入、输出信息和提示信息。
2.参考相应的资料,独立完成课程设计任务。
3.交规范课程设计报告和软件代码。
2 课程设计原理2.1 课设题目粗略分析根据课设题目要求,拟将整体程序分为三大模块。
此三个模块相互独立,没有嵌套调用的情况,以下是三个模块的大体分析:1.首先依次定义字符类型栈、整型栈、运算符栈和操作数栈,构造运算符栈和操作数栈,然后运算符、操作数依次入栈。
2. 依次读入表达式,若是操作符即进OPND栈,若是运算符即进OPTR栈。
顺序栈的存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置,base为栈底指针,在顺序栈中,它始终指向栈底,即top=base可作为栈空的标记,每当插入新的栈顶元素时,指针top增1,删除栈顶元素时,指针top减1。
3. 按照运算符的优先级别对表达式进行求值运算。
2.2 原理图介绍该功能模块图介绍了这个程序的主要功能。
2.2.1 功能模块图图2.1功能模块图如图2.1所示,要实现表达式的求值,即必须要实现存储、读取和计算三项功能。
算术表达式的求解-数据结构课程设计报告

算术表达式的求解-数据结构课程设计报告数据结构》课程设计报告书题目:算术表达式的求解系别:计算机科学与应用数据结构课程设计目录一、需求分析1、设计要求:本程序需要实现对算术表达式的求解功能,可以支持基本的四则运算,包括加、减、乘、除,同时还需要支持括号的使用。
2、设计构想:我们将使用栈来实现算术表达式的求解。
具体地,我们将把中缀表达式转换为后缀表达式,然后再利用栈来求解后缀表达式。
二、概要设计1、本程序包含的模块:本程序包含两个模块:中缀表达式转后缀表达式模块和后缀表达式求解模块。
三、详细设计1、定义栈结构我们定义一个栈结构,用来存储算术表达式中的运算符和操作数。
具体地,栈中的每个元素都包含两个属性:元素的值和元素的类型。
元素的值可以是一个数字或一个运算符,元素的类型可以是数字或运算符。
我们使用一个数组来实现栈的结构。
为了方便起见,我们还需要定义一些基本的栈操作,如入栈、出栈、判断栈是否为空等。
2、栈的基本操作栈是一种常见的数据结构,具有后进先出(LIFO)的特点。
栈的基本操作包括初始化栈、入栈、出栈、取栈顶元素和运算模块。
1) 初始化栈初始化栈是指将栈的各项属性设置为初始状态。
通常包括将栈顶指针设为-1,表示栈为空。
2) 入栈入栈是指将元素压入栈顶。
入栈操作需要将栈顶指针加1,并将元素存入栈顶位置。
3) 出栈出栈是指将栈顶元素弹出。
出栈操作需要将栈顶元素取出,并将栈顶指针减1.4) 取栈顶元素取栈顶元素是指获取栈顶元素的值,但不将其弹出。
取栈顶元素操作只需要返回栈顶元素的值即可。
5) 运算模块栈可以用于实现各种运算,例如中缀表达式的转换和计算、括号匹配等。
运算模块需要根据具体需求进行设计和实现。
3、判断运算符的优先级在进行中缀表达式的转换和计算时,需要判断运算符的优先级。
通常采用栈来实现这一功能。
具体实现方法是将运算符入栈,当遇到新的运算符时,将其与栈顶运算符进行比较,如果新运算符的优先级高于栈顶运算符,则将其入栈,否则将栈顶运算符弹出并输出,直到新运算符可以入栈为止。
数据结构课程设计算术表达式求值-计算器(Word)

高级语言程序设计《算术表达式求值》课程设计报告算术表达式求值系统可以实现实现对算术四则混合运算表达式求值,并打印求值过程中运算符栈、操作数栈的变化过程。
第二章系统分析开始运行时界面如下:你可以输入一个表达式,按E对其进行求值。
#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <string.h>#define N 100double numStack[N]={0};//操作数栈int numTop;char opStack[N];//运算符栈int opTop;void print_num(double str1[],int n) {int i;printf("\n操作数栈:\n");for(i=0;i<n;i++)printf("%g ",str1[i]);}void print_op(char str2[],int m) {int j;printf("\n运算符栈:\n");for(j=0;j<m;j++)printf("%c ",str2[j]);}int op(char ch)//判断运算符优先级{if(ch=='+'||ch=='-') return 2;if(ch=='*'||ch=='/') return 3;if(ch=='(') return -1;return 0;}double result(double num1,char op,double num2)//计算{if(op=='+') return num1+num2;if(op=='-') return num1-num2;if(op=='*') return num1*num2;if(op=='/') return num1/num2;return 0;}int compute(char str[]){double num=0;int i=0,j=1,k=1;numTop=opTop=0;while(str[i]!='\0'||opTop>0){if(str[i]>='0'&&str[i]<='9')num=num*10+str[i]-'0';else if( k==1&&str[i]=='-'&&(i==0||op(str[i-1])) )k=-1;else{if(i>0&&!op(str[i-1])&&str[i]!='('&&str[i-1]!=')') {numStack[numTop++]=num*k;if(opTop!=0&&numTop!=0)print_num(numStack,numTop);num=0; j=1; k=1;}if(opTop==0||str[i]=='('){opStack[opTop++]=str[i];print_op(opStack,opTop);}else if(str[i]==')'){while(opTop>0&&opStack[--opTop]!='('){numStack[numTop-2]=result(numStack[numTop-2],opStack[opTop],numStack[numTop-1]);if(opTop!=0&&numTop!=0){print_num(numStack,numTop);print_op(opStack,opTop);}numTop--;}if(opStack[opTop]!='(') return 0;}else{if(str[i]=='\0'&&numTop==0) return 0;while(opTop>0&&op(str[i])<=op(opStack[opTop-1])){numStack[numTop-2]=result(numStack[numTop-2],opStack[--opTop],numStack[numTop-1]);if(opTop!=0&&numTop!=0){print_num(numStack,numTop-1); print_op(opStack,opTop);}numTop--;}if(str[i]!='\0')opStack[opTop++]=str[i];if(opTop!=0&&numTop!=0)print_op(opStack,opTop);}}if(str[i]!='\0')i++;}if(numTop!=1||opTop!=0)return 0;return 1;}void menu(){system("cls");printf("_______________________________\n");printf(" Clear(C) | Equal(E) | Quit(Q) \n");printf("-------------------------------\n");}int main(void){int i=0,j=0,k;char str[N]="\0";char num[N]="\0";char save[N]="\0";char ch;double temp;unsigned long temp2;menu();printf("input an expression,press key 'E' to compute\n");ch=getch();while( 1 ){if(ch==')'||op(ch)||ch>='0'&&ch<='9'){str[i++]=ch;str[i]='\0';menu();printf("input an expression,press key 'E' to compute\n"); printf("%s",str);if( ch=='-'&&(i==1||op(str[i-2]))||ch>='0'&&ch<='9' ){num[j++]=ch;num[j]='\0';}elsej=0;}if(ch=='C'||ch=='c'){if(strlen(str))str[--i]='\0';menu();printf("input an expression,press key 'E' to compute\n");printf("%s",str);}if(ch=='E'||ch=='e'){if(compute(str)){printf("\n=%g\n",numStack[0]); j=0; temp=numStack[0];if(temp<0){temp=-temp;num[j++]='-';num[j]='\0';}temp2=(unsigned long)temp;k=1;while(temp2/k>=10) k*=10;while(k){num[j++]=temp2/k+'0';num[j]='\0';temp2=temp2%k;k/=10;}temp=temp-(int)temp;if(temp!=0){num[j++]='.';num[j]='\0';temp+=0.0000005;}for(k=6;k>0;k--){if(temp==0) break;temp*=10;num[j++]=(int)temp+'0';num[j]='\0';temp=temp-(int)temp;}}i=0; j=0; str[0]='\0';}if(ch=='Q'||ch=='q'){printf("\nare you sure to quit?(Y/N)\n");ch=getch();if(ch=='Y'||ch=='y') break;else{menu();printf("input an expression,press key 'E' to compute\n");printf("%s",str);}}ch=getch();}return 0;}第五章系统测试1.先输入: 3+2*5 后按E求值2.再输入:12/4-5 后按E求值3.再输入Q4.输入Y,退出系统。
c_语言_算术表达式的求值__数据结构_课程设计

//算术表达式的求值//济南大学信息学院计算机数据结构课程设计/*【问题描述】表达式计算式实现程序设计语言的的基本问题之一,也是栈的应用的一个典型例子,设计一个程序,演示用运算符优先法对算术表达式的求值的过程。
*///main.cpp#include "iostream.h"#include "stdlib.h"#include "public.h"#include "stack.h"//using namespace std;LinkStack OPTR;//操作符栈int Allnum[100]={0}; //储存所有的运算数int NUM[100]={0};//操作数栈int n=0;void calcu(){int x1,x2,x;char p;//弹出一个运算符Pop(OPTR,p);//弹出两个操作数x2=NUM[n--];x1=NUM[n--];//进行一次运算switch(p) {case '+':x=x1+x2;break;case '-':x=x1-x2;break;case '*':x=x1*x2;break;case '/':x=x1/x2;//结果压入操作数栈NUM[++n]=x;}int EvaluateExpression(char *p){InitStack(OPTR);InitStack(OPND);int i=0;char temp;int num=0;while( *p!='\0' )switch(*p){case '+': case '-':while ( (GetTop(OPTR,temp))!=ERROR && (temp!='('))//执行先遇到的加、减运算calcu();//当前运算符进栈Push(OPTR,*p);//读下一个字符p++;break;case '*': case '/':if ( GetTop(OPTR,temp)==OK && (temp=='*') || (temp=='/')) //执行先遇到的乘、除运算calcu();//当前运算符进栈Push(OPTR,*p);//读下一个字符p++;break;case '('://左括号进栈Push(OPTR,*p);//读下一个字符p++;break;case ')':while ( GetTop(OPTR,temp)==OK && temp!='(' )//执行括号内的加、减、乘、除运算calcu();//弹出左括号char e;Pop(OPTR,e);//读下一个字符p++;break;default://把字符串转换成整数值//int num=strInt(p);num=0;do {num=10*num+*p-'0';p++;} while((*p>='0')&&(*p<='9'));//char strnum[10];//NumString(num,strnum);//将num转换为字符串strnum//操作数进栈NUM[++n]=num;//s1[++t1]=v;Allnum[i++]=num;};while ( GetTop(OPTR,temp)==OK )calcu();//返回结果//printf("%d \n",NUM[1]);return NUM[n];}//EvaluateExpressionvoid main(){char a[100];//="5+(9-2*3)^2+3*(2+1)"; //="5*(40+6)-39";5+(9-2*3)^2+3*(2+1)int i=0;start:cout<<"算数表达式:_" ;cin>>a;cout<<EvaluateExpression(a)<<endl;//system("pause");cout<<"----------------"<<endl;goto start;}//public.henum Status{OK,ERROR,}; //定义枚举类型int strInt(char *p){//把字符串转换成整数值int num=0;do {num=10*num+*p-'0';p++;} while((*p>='0')&&(*p<='9'));return num;}///////////数字转换字符串void convert(int abc,char a[],int &i_num){if( abc/10!=0 )convert(abc/10,a,i_num);a[i_num]=abc%10+'0';i_num++;}void NumString(int abc,char a[]){if(abc<0) abc=-abc;int i_num=0;convert(abc,a,i_num);a[i_num]='\0';}//////////////////stack.h//typedef char char;typedef struct SNode{char data; //数据域struct SNode *next; //指针域}SNode,*LinkStack; //定义链栈结点Status InitStack( LinkStack &S ){//将S初始化为一个空的链栈S=( LinkStack ) malloc ( sizeof( SNode ) );if( S==NULL ) return ERROR; //内存空间申请不成功S->next=NULL;return OK;}Status DestroyStack(LinkStack &S){//销毁栈SLinkStack p;while(S->next){p=S->next;S->next=p->next;free(p);}free(S);return OK;}Status StackIsEmpty(LinkStack S){//判断栈是否为空if (S->next==NULL) return OK;return ERROR;}Status Push(LinkStack &S, char e){//将数据元素e插入到栈S的栈顶LinkStack p;p=( LinkStack ) malloc ( sizeof( SNode ) );if( p==NULL ) return ERROR;p->data=e;p->next=NULL; //创建新结点p->next=S->next;S->next=p; //插入return OK;}Status Pop(LinkStack &S, char &e){//将栈S的栈顶元素出栈,并存放到e中LinkStack p;if( S->next==NULL ) return ERROR; //空队出错p=S->next; //记住要删除的结点S->next=p->next; //栈顶元素p出栈e=p->data;free(p); //释放存储空间return OK;}Status GetTop(LinkStack S, char &e){LinkStack p;//char e;if( S->next==NULL ) return ERROR; //空队出错p=S->next;e=p->data;return OK;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
目录1.前言 (2)2.问题描述 (3)3.总体设计··········································································错误!未定义书签。
3.1 概要设计 ······································································错误!未定义书签。
3.1.1 数据结构的选择 (3)3.1.2 相关功能函数 (3)3.1.3 函数模块调用关系 (4)3.2详细设计和编码 (5)4.运行与测试 (9)4.1 上机调试 (9)4.2 算法时间和空间性能分析 (10)4.3程序运行测试结果 (11)5. 总结与心得 (13)5.1设计中难点的总结以及其它解决方案 (13)5.2 实验心得 (14)6. 用户使用说明 (16)7. 参考文献 (16)8. 附录1(源代码清单) (16)9. 附录2(成绩评定表) (25)1.前言课程设计是实践性教学中的一个重要环节,它以某一课程为基础,它可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。
课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。
《数据结构》是一门重要的专业基础课,是计算机理论和应用的核心基础课程。
在数据结构的学习和课程设计过程中,我发现它要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,都必须加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
对于我们专业来说,虽然说对技术要求不是特别高,但是在实际操作过程中,没有足够的专业知识对于编程来说是远远不可以达到要求的,所以对于这次的课程设计,我们必须要通过自己额外补充知识来完成它。
在这次的课程设计中我选择的题目是表达式的求值演示。
它的基本要求是:以字符序列的形式从终端输入语法正确的,不含变量的表达式。
利用算符优先关系,实现对算术四则混合运算表达式的求值,并演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。
表达式计算是实现程序设计语言的基本问题之一,也是栈的应用的一个典型例子。
设计一个程序,演示用算符优先法对算术表达式求值的过程。
深入了解栈和队列的特性,以便在解决实际问题中灵活运用它们,同时加深对这种结构的理解和认识。
对于表示出栈在每执行一个过程中都要输出它的变化,这点我认为在编程中是比较困难的,以我自身的能力,是不可能在规定的时间内完成任务的,所以我参考了很多有价值的书籍来帮助我完成我的程序设计。
2.问题描述(问题分析和任务定义)在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行。
因此,要求设计一个程序,利用栈演示运算符优先法对算术表达式求值的过程,利用算符有限关系,实现对算数混合四则运算表达式的求值。
程序输入:一个算术表达式,由常量、运算符和括号组成(以字符串形式输入,不含变量)。
为了简化,操作数只能为浮点数,操作符为“+”、“-”、“*”、“/”、“(”、“)”,用“#”表示结束。
程序输出:表达式运算结果,运算符栈、运算数栈、输入字符和主要操作变化过程。
测试数据:1024/(4*8) 、(20+2)*(6/2)(用于正确性检测的合法输入数据)9/0 (用于健壮性检测的非法输入数据)3.总体设计3.1概要设计3.1.1数据结构的选择任何一个表达式都是由操作符,运算符和界限符组成的。
我们分别用顺序栈来寄存表达式的操作数和运算符。
栈是限定于紧仅在表尾进行插入或删除操作的线性表。
为了实现算符优先算法,可以使用两个工作栈。
一个称做OPTR,用以寄存运算符;另一个称做OPND,用以寄存操作数或运算结果。
首先置操作数栈为空栈,表达式起始符“#”作为运算符栈的栈底元素,然后依次读入表达式的每个字符,若是操作数则进入OPND栈,若是运算符,则和OPTR栈的栈顶运算符比较优先权后做相应操作,直至整个表达式求值完毕。
栈的抽象数据类型定义ADT SqStack{数据对象:D={ai| ai ∈ElemSet,i=1,2,3……,n,n≥0}数据关系:R1={<ai-1,ai>| ai-1,ai ∈D,i=1,2,3,……,n}约定其中ai端为栈底,an端为栈顶。
操作集合:见如下相关功能函数}ADT SqStack3.1.2相关功能函数3.1.3函数模块调用关系主程序模块栈的建立及初始化模块判断输入是否结束模块判断字符类型模块输入结束输出结果运算数进栈模块运算符优先级比较模块运算符进栈模块运算符运算数出栈模块运算模块3.2详细设计和编码首先本程序定义两个顺序栈:运算符栈(OPTR)和运算数栈(OPND);OPTR栈定义如下:typedef struct{char * base; //算符栈的栈底char * top; //算符栈的栈顶int stacksize; //算符栈的最大长度}Optr_Stack;OPND栈定义如下:typedef struct{float * base; //操作数栈的栈底float * top; //操作数栈的栈顶int stacksize; //操作数栈的最大长度}Opnd_Stack;然后是主要功能函数的详细设计:(1)char Precede(char m,char n) 判断运算符优先权,返回优先权高的算符间的优先关系如下:char Precede(char m,char n)//运算符的优先级比较{if(n=='+'||n=='-')//输入符号为"+"、"-"{if(m=='('||m=='#')return '<';//栈顶元素为"("、"#",此时栈顶符号优先级低,返回"<"else return '>';//否则,栈顶符号优先级高,返回">"}else if(n=='*'||n=='/')//输入的符号为"*"、"/"{if(m==')'||m=='*'||m=='/')return '>';//栈顶元素为")"、"*"、"/",此时栈顶符号优先级高,返回">"else return '<';//否则,栈顶符号优先级低,返回"<"}else if(n=='(')return'<';//输入的符号为"(",则直接返回"<"else if(n==')')//输入的符号为")"{if(m=='(')return'=';//栈顶元素为"(",此时优先级同,返回"="else return '>';//否则,栈顶符号优先级高,返回">"}else //输入符号为其他{if(m=='#')return'=';//栈顶元素为"#",此时优先级同,返回"="else return '>';//否则,栈顶符号优先级高,返回">"}}(2)void Evaluate(Optr_Stack &S1,Opnd_Stack &S2)以字符串形式输入算数表达式,根据是运算符还是运算数来判断如何入栈函数实现如下:void Evaluate(Optr_Stack &S1,Opnd_Stack &S2){char c;float t,e;int n=0,i=1,j=0,k=0,l=0;char ch[STACK_INIT_SIZE];int s=1;int flag=0,flag2=0;float p1,p2;char ch1;Optr_Push(S1,'#');//将'#'入栈,作为低级运算符cout<<"请输入不含变量的表达式(以#结束!):\n ";cin>>ch;c=ch[0];cout<<"\n对表达式求值的操作过程如下:"<<"\n************************************************************* *******************\n"<<"步骤\t运算符栈S1\t运算数栈S2\t字符表达式\t\t栈操作过程";while(c!='#'||Optr_GetTop(S1)!='#'){cout<<"\n********************************************************* ***********************\n";cout<<i++<<"\t";Optr_DispStack(S1);cout<<"\t\t";Opnd_DispStack(S2);cout<<"\t\t";if(flag==1){k--;flag=0;}if(flag2){k+=flag2;flag2=0;}for(l=0;l<k;l++)cout<<' ';for(j=k;ch[j]!='\0';j++)cout<<ch[j];if(ch[k]!='#'&&flag!=1) {k++;flag=0;}as:if(!(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')){//输入的字符如果不是运算符号,则继续输入直到输入的是运算符为止,将非运算符转换成浮点数if(!(c=='.')&&n>=0)//小数点前面的数{e=float(c-48);n++;if(n==1)t=e;else if(n>1)t=t*10+e; //转换小数点前面的部分c=ch[s++];}if(n==-1) //小数点后面的数{e=float(c-48); //转换小数点后面的部分t=t+e/10;c=ch[s++];//最终将转换后的两部分加起来,转换成浮点数}if(c=='.'){n=-1;c=ch[s++];}if((c>='0'&&c<='9')||c=='.'){flag2++;goto as;}if(c<'0'||c>'9'){Opnd_Push(S2,t);}cout<<"\t\tOpnd_Push(S2,"<<t<<")";}else//输入的是运算符{n=0;//非运算型数据计数器清零switch(Precede(Optr_GetTop(S1),c))//比较运算符的优先级{case '<'://栈顶元素优先级低,则入栈且继续输入Optr_Push(S1,c);cout<<"\t\tOptr_Push(S1,"<<c<<")";c=ch[s++];break;case '='://栈顶元素优先级相等,脱括号并接收下一字符Optr_Pop(S1);cout<<"\t\tOptr_Pop(S1)";c=ch[s++];break;case '>'://栈顶元素优先级高,则退栈并将运算结果入栈p1=Opnd_Pop(S2);p2=Opnd_Pop(S2);ch1=Optr_Pop(S1);Opnd_Push(S2,Calculate(p2,ch1,p1));cout<<"\t\tCalculate("<<p2<<','<<ch1<<','<<p1<<')';flag=1;break;}}}cout<<"\n********************************************************* ***********************\n";cout<<i<<'\t'<<'#'<<"\t\t"<<Opnd_GetTop(S2)<<"\t\t";for(j=0;j<k;j++) cout<<' ';cout<<"#"<<"\t\t"<<"RETURN(GETTOP(S2))";cout<<"\n********************************************************* ***********************\n";if(S2.top-1==S2.base)//显示表达式最终结果cout<<"\n表达式的结果为:"<<Opnd_GetTop(S2)<<endl;else cout<<"\n表达式出错!\n";}(3)float Calculate(float a,char theta,float b)运算函数,运用else-if语句,不同的运算符则进行不同的运算;进行除法时,若分母为0,则将标志标记成错误。