数据结构课程设计-表达式求值【
数据结构表达式求值
数据结构表达式求值数据结构表达式求值=================1:引言---------本文档旨在介绍数据结构中的表达式求值问题。
首先会讨论表达式的定义和基本概念,然后介绍不同类型的表达式,并详细阐述它们的求值过程。
最后,本文还会给出一些例子和实用技巧,供读者参考。
2:表达式的定义和基本概念-------------------------表达式是由操作数、操作符和括号组成的数学式子。
它们可以用来表示数学运算、逻辑判断等。
在表达式中,操作数是指参与运算的数值或变量,操作符是指进行运算的符号,括号用于控制运算的优先级和顺序。
3:前缀表达式的求值------------------前缀表达式是一种将操作符放在操作数前面的表达式写法。
求解前缀表达式的过程可以通过使用栈来实现。
4:后缀表达式的求值------------------后缀表达式是一种将操作符放在操作数后面的表达式写法。
求解后缀表达式的过程也可以通过使用栈来实现。
5:中缀表达式的求值------------------中缀表达式是我们常见的数学表达式写法,操作符位于操作数中间。
求解中缀表达式的过程可以通过将中缀表达式转换为后缀表达式来简化。
6:表达式求值的实例-----------------本节将通过一些实例来演示表达式求值的过程,包括前缀表达式、后缀表达式和中缀表达式的求解方法。
7:实用技巧和注意事项-------------------本节将介绍一些实用的技巧和注意事项,可以帮助读者更好地理解和应用表达式求值的方法。
8:附件-------本文档不需要附加内容。
9:法律名词及注释----------------本文档中涉及的法律名词和相关注释如下:- 操作数(operand):参与运算的数值或变量。
- 操作符(operator):进行运算的符号。
- 表达式(expression):由操作数、操作符和括号组成的数学式子。
10:结束语---------本文档详细介绍了数据结构中的表达式求值问题,包括前缀表达式、后缀表达式和中缀表达式的求解方法。
数据结构表达式求值实验报告
竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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)首先定义两个栈OPTR、OPND,栈OPTR用于存放运算符,栈OPND 用于存放操作数;定义一个一维数组expr【】存放表达式串。
(2)主函数主要包括两部分:(1)判断运算符优先权,返回优先权高的;(2)操作函数。
(3)开始将‘#’入操作符栈,通过一个函数来判别算术运算符的优先级。
且规定‘#’的优先级最低。
在输入表达式的最后输入‘#’,代表表达式输入结束。
在表达式输入过程中,遇操作数则直接入栈。
遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。
如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。
(4)最初实现的加、减、乘、除及带小括号的基本运算,但考虑到实用性,后来的设计中有加上了乘方运算。
在乘方运算中借用了C库中自带的乘方函数pow。
二、概要设计1、设定栈的抽象数据类型定义:ADT Stack {数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,n≥0 }数据关系:R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }约定an端为栈顶,a1端为栈底。
基本操作:InitStack(&S)操作结果:构造一个空栈S。
DestroyStack(&S)初始条件:栈S已存在。
操作结果:栈S被销毁。
StackEmpty(S)初始条件:栈S已存在。
操作结果:若栈S为空栈,则返回TRUE,否则FALE。
StackLength(S)初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。
GetTop(S, &e)初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
ClearStack(&S)初始条件:栈S已存在。
数据结构课程设计算术表达式求值-计算器(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,退出系统。
数据结构课程设计报告-表达式求值
《数据结构》课程设计利用栈求表达式的值班级: 2学号: 100171021330姓名:吴迪指导老师:王方利用栈求表达式的值1、设计思路这个程序的关键是对数字与运算符的判断和运算符优先级的判断,以及出栈的运算。
建立两个栈,分别存储数字与运算符,栈1存运算符,栈2存数字。
依次读取表达式的字符串,先判断是数字还是运算符,如果是数字不能马上压入栈2,因为可能是大于10的数字,应该继续循环,如果还是数字,则利用计算保存数值,直到指到运算符时停止,将计算后的数字压入栈2。
压入运算符之前先将要压入的与栈顶的运算符优先级相比较,如果栈顶是‘(’而当前不是‘)’,则不需比较优先级,直接压入;如果栈顶是‘(’,当前是‘)’,则抵消(弹出‘(’,指向表达式下一个字符);若当前的运算符优先级大于栈顶的,则压入;若当前的运算符优先级小于栈內时,弹出栈顶的运算符,同时弹出两组数字,经过运算符的运算后再重新压到栈内。
为了方便判断运算结束,在存储运算符之前先将‘#’压入栈1中,在输入表达式时以‚#‛结束,所以可以以运算符==‘#’并且栈1顶==‘#’来结束运算,弹出栈2的数值,即为表达式求值的最终结果。
上述操作的算法步骤:(1)初始化算符S1,数字栈S2;,将‘#’压入算符栈S1中。
(2)读表达式字符=>w。
(3)当栈顶为‘#’并且w也是‘#’时结束;否则循环做下列步骤:(3-1)如果w是数字,存储到m,再经过计算存储到num中。
m=w-‘0’;num=num*pow(10,n)+m;n++;读下一个字符=>w,如果是运算符,则跳出循环;转3-2。
(3-2)w若是运算符,则:(3-2-1)如果栈顶为‘(’并且w为‘)’则‘(’出栈,读下一个字符=>w;转(3)。
(3-2-2)如果栈顶为‘(’或者栈顶优先级小于w优先级,则w入栈,读下一个字符=>w;转(3)。
否则:从算符栈中出栈,并从数字栈中弹出两组数字进行运算,将结果重新压入数字栈,转(3)。
表达式求值(数据结构)
表达式求值(数据结构)表达式求值(数据结构)1.引言在计算机科学中,表达式求值是一项重要的任务。
它涉及解析和计算数学或逻辑表达式,以得出最终结果。
表达式可以包括数字、变量、运算符和函数,通过采用特定的计算规则,我们可以将这些表达式转化为具体的数值或逻辑结果。
2.表达式的基本概念2.1 数字在表达式中,数字是最基本的元素。
可以是整数或浮点数,用于进行算术计算。
2.2 变量变量是用于存储和代表值的符号,它可以在表达式中使用。
变量可以通过赋值操作来获得具体的值,在表达式求值过程中,变量会被相应的数值替换。
2.3 运算符运算符是用于执行特定操作的符号。
常见的算术运算符包括加法(+), 减法(-), 乘法和除法(/)逻辑运算符包括与(&&), 或(--------) 和非(!)在表达式求值中,运算符的优先级和结合性规则是非常重要的。
2.4 函数函数是一段封装了特定功能的代码块,可以接受输入参数并返回一个结果。
在表达式中,函数可以用于处理特定的数据操作或算法。
例如,sin(x) 和cos(x) 是常见的三角函数。
3.表达式求值的步骤3.1 词法分析首先,需要对表达式进行词法分析,将表达式分解为一个个的词法单元,例如数字、变量、运算符和函数等。
词法分析可以使用正则表达式或者逐字符扫描的方式进行。
3.2 语法分析在得到词法单元序列后,需要进行语法分析,根据语法规则验证表达式的结构是否正确。
语法分析可以使用自顶向下的LL(1)分析方法或者自底向上的LR分析方法。
3.3 语义分析一旦表达式的结构验证通过,就需要进行语义分析。
语义分析的任务是根据语法树运用特定的求值规则,将表达式转换为具体的数值或逻辑结果。
在语义分析过程中,需要处理变量的赋值和函数的调用。
4.表达式求值的例子为了更好地理解表达式求值的过程,以下是一个例子:________表达式:________ 2 (3 + 4) ●5 / 24.1 词法分析:________将表达式分解为以下词法单元:________ 数字(2, 3, 4, 5), 运算符(, +, -), 括号(), 除法运算符(/)4.2 语法分析:________根据语法规则验证表达式的结构是否正确,构建语法树:________-/ \\// \\ / \\2 + 5 2/ \\3 44.3 语义分析:________根据语法树使用求值规则,依次计算每个节点的值:________●节点:________ 2 (7) ●5 / 2●节点:________ 2 7 ●5 / 2●节点:________ 14 ●5 / 2●节点:________ 14 ●2.5●最终结果:________ 11.55.附件本文档没有涉及附件。
表达式求值(数据结构)
结束算法,此时在OPND栈的栈顶得到 运算结果。
① 若ch是操作数,进OPND栈,从中缀表达式 取下一字符送入ch; ② 若ch是操作符,比较栈外icp(ch)的优先级和 栈内isp(OPTR)的优先级: 若icp(ch) > isp(OPTR),则ch进OPTR栈, 从中缀表达式取下一字符送入ch; 若icp(ch) < isp(OPTR),则从OPND栈退出 a2 和 a1 , 从 OPTR 栈 退 出 θ, 形 成 运 算 指 令 (a1)θ(a2),结果进OPND栈; 若icp(ch) == isp(OPTR) 且ch == “)”,则从 OPTR栈退出栈顶的“(”,对消括号,然后从 中缀表达式取下一字符送入ch;
优先级 操作符
1
单目-、!
2
*、/、%
3
+、-
4 <、<=、>、>=
5
==、!=
6
&&
7
||
一般表达式的操作符有4种类型:
1 算术操作符 如双目操作符(+、-、 *、/ 和%)以及单目操作符(-);
2 关系操作符 包括<、<=、==、!=、 >=、>。这些操作符主要用于比较;
3 逻辑操作符 如与(&&)、或(||)、非 (!);
38
icp (栈外) 0 8 6 4
21
isp叫做栈内(in stack priority)优先数。
icp叫做栈外(in coming priority)优先数。
操作符优先数相等的情况只出现在括号 配对或栈底的“;”号与输入流最后的“;” 号配对时。
数据结构课程设计_实验报告(一)表达式求值(计算器)
数据结构课程设计实验报告起止时间:2015.12.28-2015.12.311、输入:tan452、输出:13、执行结果::设计过程中遇到的问题及解决办法:问题:算数表达式以字符串输入,操作数和操作符的提取;解决办法:两两操作符之间如有数字将中间的数字提取强制转换成double型;参考文献:(在设计中参考的书籍、网站等资料)1. 朱振元,《数据结构——C++语言描述》,清华大学出版社,2008年,页码:2. /detail/gszhouyi/738777指导老师评议:成绩评定:指导教师签名:附件:(程序源代码)#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#define N 100#define pai 3.1415926typedef struct yxj{char operat;int rank;}yxj;typedef struct str{char data[N];}zs;void sjhs(void){char s[10],a[10];double y,x;printf("请输入(sin cos tan 角度制)表达式:\n");scanf("%s",s);if(strstr(s,"sin")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=sin(x*pai/180);}else if(strstr(s,"cos")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=cos(x*pai/180);}else if(strstr(s,"tan")!=0){int i=0,j=0;while(s[i]!='\0'){if(s[i]>='0'&&s[i]<='9')s[j++]=s[i];i++;}s[j]='\0';x=atof(s);y=tan(x*pai/180);}else{printf("格式错误\n");return;}printf("%lf\n",y);printf("*****1、继续*****\n");printf("*****0、返回上一层*****\n");scanf("%s",a);if(strcmp(a,"0")==0)return;else if(strcmp(a,"1")==0)sjhs();elseprintf("没有该选项\n");}void szys(yxj mark[]){yxj os[N];char a[10];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];ns[0]=0;printf("请输入算术(+ - * / ^)表达式(以= 结束):\n");scanf("%s",data);if(strcmp(data,"+")==0||strcmp(data,"-")==0||strcmp(data,"*")==0||strcmp(data,"/")==0 ||strcmp(data,"^")==0||strcmp(data,"=")==0){printf("格式错误\n");return;}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;switch(ch=os[--o].operat){case '+':{numb1=ns[--n];numb2=ns[--n];numb=numb1+numb2;ns[n++]=numb;break;}case '-':{numb1=ns[--n];numb2=ns[--n];numb=numb2-numb1;ns[n++]=numb;break;}case '*':{numb1=ns[--n];numb2=ns[--n];numb=numb2*numb1;ns[n++]=numb;break;}case '/':{numb1=ns[--n];numb2=ns[--n];if(numb1==0){printf("无效操作\n");return;}else{numb=numb2/numb1;ns[n++]=numb;}break;}case '^':{numb1=ns[--n];numb2=ns[--n];numb=pow(numb2,numb1);ns[n++]=numb;break;}}}}}else if(data[i]>='0'&&data[i]<='9');else if(data[i]=='.');else{printf("格式错误,请重新输入:\n");szys(mark);break;}}printf("%lf\n",ns[0]);printf("*****1、继续*****\n");printf("*****0、返回上一层*****\n");scanf("%s",&a);if(strcmp(a,"0")==0)return;else if(strcmp(a,"1")==0)szys(mark);elseprintf("没有该选项\n");}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[10];printf("*****1、四则运算计算器*****\n");printf("*****2、三角函数计算器*****\n");printf("*****0、退出*****\n");scanf("%s",&i);if(strcmp(i,"0")==0)break;else if(strcmp(i,"1")==0)szys(mark);else if(strcmp(i,"2")==0)sjhs();elseprintf("没有该选项\n");}}。
表达式求值(数据结构)(2023版)
表达式求值(数据结构) 表达式求值(数据结构)1.引言1.1 目的1.2 背景1.3 范围2.表达式类型2.1 算术表达式2.1.1 运算符2.1.2 运算数2.2 逻辑表达式2.2.1 逻辑运算符2.2.2 逻辑运算数2.3 字符串表达式2.3.1 字符串连接运算符2.3.2 字符串操作函数3.表达式求值算法3.1 递归下降分析法3.2 栈表达式求值法3.2.1 中缀表达式转后缀表达式3.2.2 后缀表达式求值4.数据结构4.1 操作数栈4.2 运算符栈4.3 后缀表达式栈5.算法实现步骤5.1 输入表达式5.2 初始化栈5.3 处理表达式字符串5.4 根据算法选择相应的方法求值5.5 输出结果6.实例演示6.1 算术表达式求值示例6.2 逻辑表达式求值示例6.3 字符串表达式求值示例7.测试与验证7.1 正常表达式测试7.2 异常表达式测试7.3 性能测试8.总结与展望8.1 本文主要工作8.2 结果评估8.3 存在问题8.4 后续工作附件:附件1、算术表达式求值示例代码附件2、逻辑表达式求值示例代码附件3、字符串表达式求值示例代码法律名词及注释:1.递归下降分析法: 一种基于上下文无关文法进行递归分析的方法,用于处理表达式求值等问题。
2.栈表达式求值法: 使用栈数据结构进行表达式求值的方法。
3.中缀表达式: 常见的数学表达式写法,运算符位于运算数之间。
4.后缀表达式: 也称为逆波兰表达式,运算符位于运算数之后。
5.操作数栈: 用于存储表达式中的操作数的栈。
6.运算符栈: 用于存储表达式中的运算符的栈。
7.后缀表达式栈: 用于存储后缀表达式的栈。
数据结构课程设计算术表达式求值
计算机科学系《数据结构课程设计》报告课题名称:算术表达式求值目录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栈中加入一个‘=‘。
数据结构课程设计 表达式的值
目录1 题目的内容及要求 (2)2 需求分析 (2)3 概要设计 (2)4 详细设计 (4)5 源代码 (6)6 运行结果及分析 (13)7 收获及体会 (14)1 题目的内容及要求从文件读取表达式,判断表达式是否合理,将表达式转换成后缀形式,按后缀表达式求值;题目涉及加减乘除,带括弧的混合运算;随时可以退出。
2 需求分析利用栈设计一个程序,该程序能够用于表达式求值,程序将读入的中缀表达式转换为后缀表达式,然后读取后缀表达式,输出结果。
本程序具有检测表达式语法是否正确的功能,如果表达式出现错误的时候,程序会提示操作人员执行的表达式不合理,语法是不能执行的。
语法正常的情况下,程序可以实现了加、减、乘、除以及带括号的基本运算。
程序在执行表达式的时候,先检查表达式是否合理,不合理则输出表达式不符合要求,合理则将中缀表达式转化为后缀表达式,然后则对表达式求值,输出结果。
3 概要设计本程序选用的是线性表数据结构。
它按照后进先出的原则存储数据,先进的数据被压入栈底,最后的数据在栈顶,需要度数据的时候才栈顶开式探出数据。
程序采用的是顺序存储结构,可以将逻辑上相邻的数据元素在物力上相邻的存储单元里,节电之间的关系由存储单元相邻的关系来决定。
选择线性表结构是因为程序是用栈来设计的,可以将优先运算的送至栈顶,低级别的运算则最后根据先后进栈的顺序来执行。
选择顺序存储结构是因为顺序存储结构存取数据数度快,占用的存储空间小。
系统的功能模块划分:Translate()的功能是将中缀表达式转换为后缀表达式DispPostfix()的功能是输出后缀表达式ProcessExpress()的功能是将原表达式进行预处理,检查符号是否匹配,转化为中缀式。
endright的功能是先对表示式的运算符进行处理,考虑其计算的优先级。
FindSymbol()的功能是对表达式的括号进行优先处理。
FindWord()的功能是检查表达式是否有语法错误。
数据结构课程设计-表达式求值问题
实验表达式求值问题1. 问题描述表达式是数据运算的基本形式。
人们的书写习惯是中缀式,如:11+22* (7-4 )/3. 中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。
表达式还有后缀表达式(如:11 22 7 4 - * 3 / + )和前缀表达式(+ 11 / * 22 - 7 4 3 )。
后缀表达式和前缀表达式中没有括号,给计算带来方便。
如后缀表达式计算时按运算符出现的先后进行计算。
本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。
2. 数据结构设计1)顺序栈类定义:首先应在类中定义成员函数,以此来完成顺序栈的相关操作,如下:class SqStackprivate:T *base; // 栈底指针int top; // 栈顶int stacksize; // 栈容量public:SqStack(int m); // 构建函数~SqStack(){delete [] base;top=0;stacksize=0;} // 析构函数void Push(T x); // 入栈T Pop(); // 出栈T GetTop(); // 获取栈顶元素int StackEmpty(); // 测栈空void ClearStack(); // 清空栈void StackTop(); // 返回栈顶指针void StackTranverse(); // 显示栈中元素};2)顺序栈类实现:对顺序栈进行初始化,初始化的首要操作就是创建一个空顺序栈。
Step1 :申请一组连续的内存空间为顺序栈使用:base=new T[m];i f(base==NULL)cout<<" 栈创建失败,退出!"<<endl; exit(1);}{Step2 :给栈顶、栈容量赋相应的值:stacksize=m;t op=-1;(2)顺序栈入栈:入栈需要在栈顶插入一个新元素并相应的调整栈顶。
数据结构表达式求值
数据结构表达式求值正文:1. 引言本文档旨在介绍数据结构中表达式求值的相关知识和算法。
通过对不同类型的表达式进行解析、转换和计算,可以实现数学运算、逻辑判断等功能。
2. 表达式基础概念2.1 表达式定义:一个由操作符(如加减乘除)、操作数(变量或常量)以及括号组成的序列。
2.2 中缀表示法:将操作符置于两个相邻的操作数之间,例如a +b c。
2.3 后缀表示法:将所有操作符都放到其相关联的两个对象后面,例如 abc+。
3. 中缀转后缀在计算机内部处理表达时通常使用后缀形势更为方便,在此我们需要先把中边形势得出来再做进一步分析与运行4.栈应用-前驱关系图这里是讲述了当遇见某些特殊字符要怎么去处理5.从左至右扫描并分类输入串:这里主要说明了如果用户给定字符串有误该怎样提示错误信息6.数字直接输出, 操作者入堆栈:当检测到当前读取元素是数字就会直接打印7 . 遇到操作符时,比较其与栈顶运算符的优先级:这里主要是讲述了当遇见某些特殊字符要怎么去处理8 . 操作者入堆栈当检测到当前读取元素是数字就会直接打印9. 遇括号则进行如下判断:如果为左括号,则将此运算符压入堆叠。
(2)如果为右括号。
则依次弹出S中的所有运算符,并加至输出串尾部, 直至删除一个相应的左括号(不包含该左扩展)。
10.重复步骤3-6 ,直至表达式结束附件:无法律名词及注释:1. 表达式求值:指对给定数学或逻辑表达式进行计算并得出结果的过程。
2. 中缀表示法:一种常用于书写和理解数学表达式的形式,其中操作符位于两个相关联的对象之间。
3. 后缀表示法(也称逆波兰表示法):一种以后置方式排列操作数和操作符来构造代数、布尔函数等合成函数公式或语言文法规范的记录方法和数据结构.。
数据结构(C语言版)课程设计报告表达式求值说明书
数据结构(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磅。
一级标题靠左,加粗。
二级大标题靠左,不加粗。
表达式求值(数据结构)
表达式求值(数据结构)表达式求值(数据结构)一、引言表达式求值是计算机科学中一个重要的概念,它是计算机程序中常见的操作之一。
通过对表达式中的运算符和操作数进行计算,可以得到表达式的结果。
本文将介绍表达式求值的相关知识和算法,并提供一个基于数据结构的表达式求值的范本。
二、基本概念1.表达式:由操作数、运算符和括号组成的符号串,用于表示一个计算过程。
2.操作数:表达式中用于参与计算的数值或变量。
3.运算符:表达式中用于进行运算的符号,如加减乘除等。
4.括号:用于控制运算优先级和改变运算次序的符号。
三、表达式求值的算法表达式求值的基本思路是通过遍历表达式字符串并利用栈来进行计算。
1.建立一个操作数栈和一个运算符栈。
2.从左到右遍历表达式字符串,依次处理每个字符。
3.如果当前字符是操作数,则直接入操作数栈。
4.如果当前字符是运算符,则进行如下处理:●如果运算符栈为空或栈顶运算符是左括号,则将当前运算符入运算符栈。
●如果当前运算符的优先级高于栈顶运算符的优先级,则将当前运算符入运算符栈。
●如果当前运算符的优先级低于或等于栈顶运算符的优先级,则从运算符栈顶取出一个运算符进行计算,并将结果入操作数栈,直到栈顶运算符的优先级低于当前运算符,然后将当前运算符入运算符栈。
5.如果当前字符是左括号,则将其入运算符栈。
6.如果当前字符是右括号,则从运算符栈顶取出一个运算符进行计算,并将结果入操作数栈,直到取出的运算符是左括号。
7.遍历完表达式字符串后,将运算符栈中剩余的运算符依次取出进行计算,并将结果入操作数栈。
8.操作数栈中最后剩下的元素即为表达式的求值结果。
四、示例代码```pythonclass ExpressionEvaluation:def __init__(self, expression):self.expression = expressionself.operators = []self.operands = []self.precedence = {'+': 1, '.': 1, '': 2, '/': 2}def evaluate(self):for char in self.expression:if char.isdigit():self.operands.append(int(char))elif char in self.precedence:while self.operators andself.operators[.1] != '(' and self.precedence[char] <= self.precedence[self.operators[.1]]:lculate()self.operators.append(char)elif char == '(':self.operators.append(char)elif char == ')':while self.operators[.1] != '(':lculate()self.operators.pop()while self.operators:lculate()return self.operands[.1]def calculate(self):operator = self.operators.pop()operand2 = self.operands.pop()operand1 = self.operands.pop()if operator == '+':self.operands.append(operand1 + operand2)elif operator == '.':self.operands.append(operand1 ●operand2) elif operator == '':self.operands.append(operand1 operand2) elif operator == '/':self.operands.append(operand1 / operand2) expression = \。
施磊磊的数据结构课程设计及报告2 表达式求值问题
课程设计题目名称表达式求值问题课程名称数据结构课程设计学生姓名施磊磊学号0813022057班级计082指导教师管致锦数据结构课程设计及报告表达式求值一、问题描述实验题目为表达式求值。
要求接受用户输入一个中缀表达式(运算符为加、减、乘、除),然后通过借助于顺序栈实现将其转换为后缀表达式并将其打印,最后求出其值。
设计主函数,使用户可以重复输入中缀表达式,求得表达式的后缀表达式和表达式的值。
二、数据结构算法设计(一)堆栈ADTADT Stack{数据:0个或多个元素的线性序列(a0,a1,...,an-1),其最大允许长度为MaxStackSize。
运算:Create(): 建立一个空栈。
Destroy(): 撤销一个栈。
IsEmpty(): 若空栈,则返回true;否则返回false。
IsFull(): 若栈满,则返回true;否则返回false。
Top(): 在x中返回栈顶元素。
若操作成功,则返回true;否则返回false。
Push(): 在栈顶插入元素x(入栈)。
若操作成功,则返回true;否则返回false。
Pop(): 从栈中删除栈顶元素(出栈)。
若操作成功,则返回true;否则返回false。
Clear(): 清除堆栈中全部元素。
}(二)顺序栈类在此题目中,借助了c++的模板抽象类来定义栈抽象数据类型,程序如下:顺序堆栈类:includetemplateclass Stack{private:T * stack; //指向数组的指针int top; //栈顶指针int maxTop; //最大栈顶指针public:Stack(); //构建一个构造函数;初始化栈void Push(T item); //进栈T Pop(); //出栈,删除栈顶元素T Peek(); //返回栈顶元素bool EmptyStack(); //判断是否为空栈~Stack() {delete []stack;}; //释放并清空栈的存储空间void Clear(){top=-1;} //清除栈中全部元素三、算法原理(一)头文件名在本程序中,运用的头文件有一些是在平时经常用到的,也有一些是少见甚至是很陌生的。
数据结构表达式求值完整篇(含实验报告范文)-
数据结构表达式求值完整篇(含实验报告范文)-1、实验目的和要求(1)深入理解栈的特点及其描述方法。
(2)能够在两种存储结构上实现栈抽象数据类型实现。
(3)掌握栈的几个典型应用算法,能灵活应用栈解决实际问题。
2、概要设计【定义所有抽象数据类型、自定义函数间的调用关系图,自定义函数的功能描述和流程图,以及主程序的流程图。
】开始定义运算符和操作数栈并初始化并ffluh(tdin)清除缓存输入每个字符并执行相应的条件语句入栈出栈//比较OPTR的栈顶元素和ch的优先级charPrecede(SElemType_OPTRtop,While(1)YEvaluateE某preion()//运算并将结果出栈Operate输出结果3、调试分析【(1)调试过程中遇到的问题是如何解决的以及对设计与实现中关键点的回顾讨论和分析;(2)算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的分析)和改进设想;(3)经验和体会等。
】1.栈的定义、初始化、出栈进栈、取栈顶元素等步骤不难就先把结构打好了2.操作数和运算符分别入不同的栈char->int进操作数栈先考虑了小于10的整数直接进栈,重点是运算符的优先级这块函数的编写3前面的都听简单的,就是小数编写这块想了很久,将单个字符转为整数后还要定一个doublep;使依次输入的数成一个小数->p.在小数入栈使要考虑放在那条if语句中,防止在运算结果入栈后p再次入栈,又定义了intflag;通过flag的值判定p是否入栈。
并且成功入栈后p,q都要回到初始状态。
小数解决4.负数部分讨论一开始就有负数和运算符后面有负数的情况。
(比较容易)右图重点定义了low做判定符号的标志。
如果在运算符后输入负号则low=-1(将p入栈时入栈的是p某low),继续输入ch。
总结:我觉得写的好的地方在于定义了flag,low分别作为小数入栈和负号与减号区别的条件。
第一次写这么长的代码,还有就是将输入的字符再转到小数这段代码可以留着很有用。
数据结构课设 表达式求值
《计算表达式》课程设计报告标题:计算表达式单位:报告人:指导教师:编程环境:VC6时间:2011年12月20日一、设计要求对于输入的一个中缀表达式,判断表达式是否合法。
如果合法,把中缀表达式转换成一棵二叉树,然后通过后根遍历计算表达式的值,输出运算结果。
合法表达式不能为空,可以出现在表达式中的字符有:*运算符“+”、“-”、“*”、“/”;*左右括号“(”、“)”;*整数(可以是多位的);*空格符和制表符。
例如:表达式为“20+(3*(4+46)-6)/2-134”将得到结果-42。
数据结构采用二叉树的链接表示。
二、题目分析由设计要求可以确定程序的几大模块,读入源程序(1)读入中缀表达式(2)从中缀表达式ex(长度为n)创建二叉树(3)后根遍历计算表达式的值(4)输出运算结果进一步确定几个子程序及其相互之间的调用关系为:三.流程图四.全局变量与子程序功能说明(1)int extoBinTree(PBinTree pbtree,const char *ex,int n)从中缀表达式ex(长度为n)创建二叉树。
若是一个合法的表达式,则返回TRUE,且算法结束时*pbtree存放二叉树的根节点的地址;否则返回FALSE(2)int cal(BinTree btree,int*presult)计算二叉树btree所代表的表达式的值。
若是一个合法的表达式,则返回TRUE,且算法结束时*presult中存放计算结果;否则,返回FALSE.(3)void delete_BTree(PBinTree ptree){BinTree temp=(*ptree);if(temp==NULL) return;delete_BTree(&(temp->llink));delete_BTree(&(temp->rlink));free(temp);}作用为,当输入的程序有误时,或者一段表达式已经运算结束时清除储存空间,为下一段表达式的计算作准备。
数据结构表达式求值(可以求小数与多位数)
//栈顶压入一个数
S.top++; } char PopOPTR(SqStackOPTR &S,char &e){ --S.top; e=*S.top; return e; } float PopOPND(SqStackOPND &S,float &e){ --S.top; e=*S.top; return e; } Status GetTopOPTR(SqStackOPTR &S,char &e){ e=*(S.top-1); return e; } float GetTopOPND(SqStackOPND &S,float &e){ e=*(S.top-1); return e; } unsigned char Prior[7][7] = { '>','>','<','<','<','>','>', '>','>','<','<','<','>','>', '>','>','>','>','<','>','>', '>','>','>','>','<','>','>', // 算符间的优先关系 //取栈顶元素
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计-表达式求值【完整版】.数据结构课程设计——表达式求值大学XXXXXX 《数据结构》课程设计报告班级:学号:姓名:指导老师:页 18 共页 2 第数据结构课程设计——表达式求值目录一算术表达式求值一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码二感想体会与总结页 18 共页 3 第数据结构课程设计——表达式求值算术表达式求值一、需求分析一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
程序的主要功能二、(1)从键盘读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
三、程序运行平台Visual C++ 6.0版本数据结构四、本程序的数据结构为栈。
(1)运算符栈部分:struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针int stacksize; //栈的长度};int InitStack (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{牰湩晴尨运算符栈为空!\n);return ERROR;}elsee=*(s.top-1); //栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OK页 18 共页 4 第数据结构课程设计——表达式求值return OK;}int Push(SqStack &s,char e) //运算符入栈{if (s.top-s.base >= s.stacksize){牰湩晴尨运算符栈满!\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{牰湩晴尨运算符栈为空!\n);return ERROR;}else{e=*--s.top; //栈不为空的时候用e做返回值,删除S的栈顶元素,并返回OKreturn OK;}}int StackTraverse(SqStack &s) //运算符栈的遍历{char *t;t=s.base ;if (s.top==s.base){牰湩晴尨运算符栈为空!\n); //栈为空栈的时候返回ERRORreturn ERROR;while(t!=s.top){printf( %c,*t); //栈不为空的时候依次取出栈内元素t++;}页 18 共页 5 第数据结构课程设计——表达式求值return ERROR;}(2)数字栈部分:struct SqStackn //定义数栈{int *base; //栈底指针int *top; //栈顶指针int stacksize; //栈的长度};int InitStackn (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){牰湩晴尨运算数栈为空!\n); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OK return OK;int Pushn(SqStackn &s,int e) //数栈入栈{if (s.top-s.base >=s.stacksize){牰湩晴尨运算数栈满!\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; //栈顶指针变化return OK;页 18 共页 6 第数据结构课程设计——表达式求值}int Popn(SqStackn &s,int &e) //数栈出栈{if (s.top==s.base){printf( 运算符栈为空!\n); //栈为空栈的视时候,返回ERRORreturn ERROR;}else{e=*--s.top; //栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OK return OK;}}int StackTraversen(SqStackn &s) //数栈遍历{int *t;t=s.base ;if (s.top==s.base){printf( 运算数栈为空!\n); //栈为空栈的时候返回ERRORreturn ERROR;}while(t!=s.top){printf( %d,*t); //栈不为空的时候依次输出t++;}return ERROR;}五、算法及时间复杂度1、算法:建立两个不同类型的空栈,先把一个‘# '压入运算符栈。
输入一个算术表达式的字符串(以‘#'结束),从第一个字符依次向后读,把读取的数字放入数字栈,运算符放入运算符栈。
判断新读取的运算符和运算符栈顶得运算符号的优先级,以便确定是运算还是把运算符压入运算符栈。
最后两个‘#'遇到一起则运算结束。
数字栈顶的数字就是要求的结果。
2、时间复杂度:O(n)数据压缩存储栈,其操作主要有:建立栈int Push(SeqStack *S, char x)页 18 共页 7 第数据结构课程设计——表达式求值入栈int Pop(SeqStack *S, char x)出栈。
以上各操作运算的平均时间复杂度为O(n),其主要时间是耗费在输入操作。
六、测试用例如图所示。
最终结果如图所示:七、源代码页 18 共页 8 第数据结构课程设计——表达式求值/**************************************************************************************** **********第七题算术表达式求值[问题描述]一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。
假设操作数是正整数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。
引入表达式起始、结束符是为了方便。
编程利用“算符优先法”求算术表达式的值。
[基本要求](1)从键盘读入一个合法的算术表达式,输出正确的结果。
(2)显示输入序列和栈的变化过程。
***************************************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <conio.h>#include <ctype.h>#define OK 1#define ERROR 0#define STACK_INIT_SIZE 100//#define STACKINCREMENT 10//========================================================// 以下定义两种栈,分别存放运算符和数字//========================================================//*******************运算符栈部分*************************struct SqStack //定义栈{char *base; //栈底指针char *top; //栈顶指针int stacksize; //栈的长度};int InitStack (SqStack &s) //建立一个空栈S{if (!(s.base = (char *)malloc(50 * sizeof(char))))exit(0);页 18 共页 9 第数据结构课程设计——表达式求值s.top=s.base;s.stacksize=50;return OK;}char GetTop(SqStack s,char &e) //运算符取栈顶元素{if (s.top==s.base) //栈为空的时候返回ERROR{牰湩晴尨运算符栈为空!\n);return ERROR;}elsee=*(s.top-1); //栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OKreturn OK;}int Push(SqStack &s,char e) //运算符入栈{if (s.top-s.base >= s.stacksize){牰湩晴尨运算符栈满!\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{牰湩晴尨运算符栈为空!\n);return ERROR;}else{页 18 共页 10 第数据结构课程设计——表达式求值e=*--s.top; //栈不为空的时候用e做返回值,删除S的栈顶元素,并返回OK return OK;}}int StackTraverse(SqStack &s) //运算符栈的遍历{char *t;t=s.base ;if (s.top==s.base){牰湩晴尨运算符栈为空!\n); //栈为空栈的时候返回ERRORreturn ERROR;}while(t!=s.top){printf( %c,*t); //栈不为空的时候依次取出栈内元素t++;}return ERROR;}//**********************数字栈部分***************************struct SqStackn //定义数栈{int *base; //栈底指针int *top; //栈顶指针int stacksize; //栈的长度};int InitStackn (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) //数栈取栈顶元素{页 18 共页 11 第数据结构课程设计——表达式求值if (s.top==s.base){牰湩晴尨运算数栈为空!\n); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}int Pushn(SqStackn &s,int e) //数栈入栈{if (s.top-s.base >=s.stacksize){牰湩晴尨运算数栈满!\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; //栈顶指针变化return OK;}int Popn(SqStackn &s,int &e) //数栈出栈{if (s.top==s.base){printf( 运算符栈为空!\n); //栈为空栈的视时候,返回ERRORreturn ERROR;}else{e=*--s.top; //栈不空的时候,则删除S的栈顶元素,用e返回其值,并返回OKreturn OK;}}int StackTraversen(SqStackn &s) //数栈遍历页 18 共页 12 第数据结构课程设计——表达式求值{int *t;t=s.base ;if (s.top==s.base){printf( 运算数栈为空!\n); //栈为空栈的时候返回ERRORreturn ERROR;}while(t!=s.top){printf( %d,*t); //栈不为空的时候依次输出t++;}return ERROR;}//======================================================== // 以下定义函数//======================================================== int Isoperator(char ch) //判断是否为运算符,分别将运算符和数字进入不同的栈{switch (ch){case '+':case '-':case '*':case '/':case '(':case ')':case '#':return 1;default:return 0;}}int Operate(int a, char op, int b) //运算操作{int result;switch(op){case '+':result=a+b;break;页 18 共页 13 第数据结构课程设计——表达式求值case '-':result=a-b;break;case '*':result=a*b;break;case '/':result=a/b;break;}return result;}char Precede(char ch1, char ch2) //运算符优先级的比较{char p;switch(ch1){case '+':case '-':if (ch2=='+'||ch2=='-'||ch2==')'||ch2=='#')p = '>'; //ch1运算符的优先级小于ch2运算符elsep = '<';break;case '*':case '/':if (ch2 == '(')p = '<';elsep = '>';break;case '(':if (ch2 == ')')p = '=';else if (ch2 == '#'){printf( 表达式错误!运算符不匹配!\n) ;exit(0);}elsep = '<';break ;页 18 共页 14 第数据结构课程设计——表达式求值case ')':if (ch2 == '('){printf( 表达式错误!运算符不匹配!\n) ;exit(0);}elsep = '>';break ;case '#':if (ch2 == ')'){printf( 表达式错误!运算符不匹配!\n) ;exit(0);}else if (ch2 == '#')p = '=';elsep='<';break;}return p;}//======================================================== // 以下是求值过程//======================================================== int EvaluateExpression() //参考书p53算法3.4{int a, b, temp, answer;char ch,op,e;char *str;int j = 0;SqStackn OPND; //OPND为运算数字栈SqStack OPTR; //OPTR为运算符栈InitStack(OPTR);Push(OPTR,'#'); //,所以此栈底是'#',因为运算符栈以'#'作为结束标志InitStackn(OPND);// printf(\\n按任意键开始求解:\n\n);// ch=getch();printf(\请输入表达式并以'#'结束:\n);str =(char*)malloc(50*sizeof(char));gets(str);页 18 共页 15 第数据结构课程设计——表达式求值ch=str[j]; //ch是字符型的,而e是整型的整数j++;GetTop(OPTR,e); //e为栈顶元素返回值while (ch!='#' || e!='#'){if (!Isoperator(ch)) //遇到数字,转换成十进制并计算{temp=ch-'0'; //将字符转换为十进制数ch=str[j];j++;while(!Isoperator(ch)){temp=temp*10 + ch-'0'; //将逐个读入运算数的各位转化为十进制数ch=str[j];j++;}Pushn(OPND,temp);}else if (Isoperator(ch)) //判断是否是运算符,不是运算符则进栈switch (Precede(e,ch)){case '<' : Push(OPTR,ch); // 栈顶元素优先权低ch = str[j++];printf(\\n 运算符栈为:\n); //输出栈,显示栈的变化StackTraverse(OPTR);printf(\运算数栈为:\n);StackTraversen(OPND);break;case '=' : Pop(OPTR,op); // 脱括号并接收下一字符ch = str[j++] ;printf(\\n 运算符栈为:\n);StackTraverse(OPTR);printf(\数栈为:\n);StackTraversen(OPND);break;case '>' : Pop(OPTR,op); //弹出最上面两个,并运算,把结果进栈Popn(OPND,b);Popn(OPND,a);Pushn(OPND,Operate(a,op,b));printf(\\n 运算符栈为:\n);页 18 共页 16 第数据结构课程设计——表达式求值StackTraverse(OPTR);printf(\数栈为:\n);StackTraversen(OPND);}else{牰湩晴尨您的输入有问题,请检查重新输入!);exit(0);}GetTop(OPTR,e); //取出运算符栈最上面元素是否是'#'} //whileGetTopn(OPND,answer); //已输出。