最新《数据结构》算术表达式求值
数据结构表达式求值实验报告

竭诚为您提供优质文档/双击可除数据结构表达式求值实验报告篇一:数据结构实验二——算术表达式求值实验报告《数据结构与数据库》实验报告实验题目算术表达式求值学院:化学与材料科学学院专业班级: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!二、概要设计拟采用两种类型的展分别对操作数和操作符进行操作。
数据结构实验报告--表达式求值

void Initstack1(stack1 *s>
{
(*s>->base = (int *>malloc(SIZE * (sizeof(int>>>
。
(*s>->top = (*s>->base
。
(*s>->stacksize = INCREMENT 。
}
int Ifempty2(stack2 *s>
<6)中缀转后缀并计算模块:
( 三 > 详细设计
1.元素类型 , 结点类型和指针类型:
typedef struct{
int stacksize 。 int *base 。
int *top 。
}Sqstack1,*stack1 。
typedef struct{
int stacksize 。
char *base 。
{
if(((a=='*'>||(a=='/'>>&&((b=='+'>||(b=='-'>||(b=='#'>>>
5PCzVD7HxA
return '>'
。
else
return '<'
。
}
<4)运算符操作模块;
int Operate(int a,char b,int c>
{
int t 。
if(b == '+'> t = a + c
{
数据结构-算术表达式求值(含需求分析和源代码)

需求分析(附代码)一、需求分析(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,退出系统。
数据结构表达式求值(中缀)实验报告

数据结构表达式求值(中缀)实验报告题目名称表达式求值学号姓名指导教师日期一1. 问题描述:在计算机中,算术表达式由常量、变量、运算符和括号组成。
由于不同的运算符具有不同的优先级,又要考虑括号,因此,算术表达式的求值不可能严格地从左到右进行,在程序设计时,借助栈实现。
2. 表达式求值这个程序,主要利用栈和数组,把运算的先后步骤进行分析并实现简单的运算,以字符列的形式从终端输入语法的正确的、不含变量的整数表达式。
利用已知的算符优先关系,实现对算术四则运算的求值,在求值中运用栈、运算栈、输入字符和主要操作的变化过程。
该程序相当于一个简单的计算机计算程序,只进行简单的加减乘除和带括号的四则运算。
1、基本思想(中缀表达式求值)要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式,要了解算术四则运算的规则即:(1)先乘除后加减;(2)从左到右计算;(3)先括号内,后括号外。
下表定义的运算符之间的关系:b + - * / () # a+ > > < < < > > _ > > < < < > > * > > > > < > > / > > > > < > > ( < < < < < = ) > > > > > > # < < < < < =为了实现运算符有限算法,在程序中使用了两个工作栈。
分别是:运算符栈OPTR,操作数栈OPND.基本思想:(1)首先置操作数栈为空栈,表达式起始符“#”为运算符栈的栈底元素;(2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符则和OPTR栈得栈顶运算符比较优先级后作相应操作。
算术表达式求值-数据结构实验报告

课程设计报告(20 -20 学年第学期)报告题目:算术表达式求值课程名称:数据结构任课教员:专业:学号:姓名:二0一年月日摘要:现代科学技术高速发展,各种高科技产品频频问世,而各种技术的基础都离不开基本的表达式求值,它虽然简单,但却是任何复杂系统的基本执行操作。
栈是一种重要的线性结构,从数据结构的角度看,它是一种特殊的线性表,具有先入先出的特点。
而算符优先法的设计恰巧符合先入先出的思想。
故我们基于栈这种数据结构,利用算符优先法,来实现简单算术表达式的求值。
关键字:算符优先法;算术表达式;数据结构;栈一、课题概述1、问题描述一个算术表达式是由运算数、运算符、界限符组成。
假设操作数是正整数,运算符只含有加“+”、减“-”、乘“*”、除“/”四种二元运算符,界限符有左括号“(”、右括号“)”和表达式起始、结束符“#”。
利用算符优先法对算术表达式求值。
2、设计目的(1)通过该算法的设计思想,熟悉栈的特点和应用方法;(2)通过对算符优先法对算术表达式求值的算法执行过程的演示,理解在执行相应栈的操作时的变化过程。
(3)通过程序设计,进一步熟悉栈的基本运算函数;(4)通过自己动手实现算法,加强从伪码算法到C语言程序的实现能力。
3、基本要求:(1)使用栈的顺序存储表示方式;(2)使用算符优先法;(3)用C语言实现;(4)从键盘输入一个符合要求的算术表达式,输出正确的结果。
4、编程实现平台Microsoft Visual C++ 6.0二、设计思路及采取方案1、设计思路:为了实现算符优先法,可以使用两个工作栈。
一个称做OPTR ,用以寄存运算符;另一个称做OPND ,用以寄存操作数或运算结果。
算法的基本思想是:(1)首先置操作数栈为空栈,表达式起始符“#”作为运算符栈的栈底元素; (2)依次读入表达式中每个字符,若是操作数则进入OPND 栈,若是运算符则和OPTR 栈的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕(即OPTR 栈的栈顶元素和当前读入的字符均为“#”)。
表达式求值(数据结构)

结束算法,此时在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)优先数。
操作符优先数相等的情况只出现在括号 配对或栈底的“;”号与输入流最后的“;” 号配对时。
最新《数据结构》算术表达式求值

二课程设计2——算术表达式求值一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码三感想体会与总结算术表达式求值一、需求分析一个算术表达式是由操作数(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{printf("运算符栈为空!\n");return ERROR;}elsee=*(s.top-1); //栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OKreturn OK;}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的栈顶元素,并返回OKreturn 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; //栈的长度};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){printf("运算数栈为空!\n"); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}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; //栈顶指针变化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) //数栈遍历{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、算法:建立两个不同类型的空栈,先把一个‘# ’压入运算符栈。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
二课程设计2——算术表达式求值一、需求分析二、程序的主要功能三、程序运行平台四、数据结构五、算法及时间复杂度六、测试用例七、程序源代码三感想体会与总结算术表达式求值一、需求分析一个算术表达式是由操作数(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{printf("运算符栈为空!\n");return ERROR;}elsee=*(s.top-1); //栈不为空的时候用e做返回值,返回S的栈顶元素,并返回OKreturn OK;}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的栈顶元素,并返回OKreturn 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; //栈的长度};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){printf("运算数栈为空!\n"); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}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; //栈顶指针变化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) //数栈遍历{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)入栈int Pop(SeqStack *S, char x)出栈。
以上各操作运算的平均时间复杂度为O(n),其主要时间是耗费在输入操作。
六、测试用例如图所示。
最终结果如图所示:七、源代码/*********************************************************************************************** ***第七题算术表达式求值[问题描述]一个算术表达式是由操作数(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);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的栈顶元素,并返回OKreturn OK;}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的栈顶元素,并返回OKreturn 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;}//**********************数字栈部分***************************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){printf("运算数栈为空!\n"); //栈为空的时候返回ERRORreturn ERROR;}elsee=*(s.top-1); //栈不为空的时候,用e作返回值,返回S的栈顶元素,并返回OKreturn OK;}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; //栈顶指针变化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) //数栈遍历{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;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 ;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\n");// ch=getch();printf("\n请输入表达式并以'#'结束:\n");str =(char*)malloc(50*sizeof(char));gets(str);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 运算符栈为:\n"); //输出栈,显示栈的变化StackTraverse(OPTR);printf("\n 运算数栈为:\n");StackTraversen(OPND);break;case '=' : Pop(OPTR,op); // 脱括号并接收下一字符ch = str[j++] ;printf("\n\n 运算符栈为:\n");StackTraverse(OPTR);printf("\n 数栈为:\n");StackTraversen(OPND);break;case '>' : Pop(OPTR,op); //弹出最上面两个,并运算,把结果进栈Popn(OPND,b);Popn(OPND,a);Pushn(OPND,Operate(a,op,b));printf("\n\n 运算符栈为:\n");StackTraverse(OPTR);printf("\n 数栈为:\n");StackTraversen(OPND);}else{printf("您的输入有问题,请检查重新输入!");exit(0);}GetTop(OPTR,e); //取出运算符栈最上面元素是否是'#' } //whileGetTopn(OPND,answer); //已输出。