后缀表达式求值_数据结构设计
表达式求值(数据结构-栈的应用)

表达式求值(数据结构-栈的应⽤)⼀.问题描述:限制:只含有‘+’,‘-’,‘*’,‘/ ’和圆括号,正整数。
表⽰:字符数组,栈。
中缀表达式:在程序语⾔中,运算符位于两个运算数中间的表达式称为中缀表达式,例如 1+2*3.中缀表达式运算规则:先乘除,后加减,从左到右,先括号内,后括号外,因此中缀表达式不仅要判断运算符的优先级,⽽且还有处理括号。
后缀表达式:运算符在运算数的后⾯,如1+2*3的后缀表达式:1 2 3*,在后缀表达式中已经考虑了运算符的优先级,没有括号,只有运算数和运算符。
后缀表达式的运算:按照运算符的次序进⾏的。
例如123*+,从左到右扫描时,第⼀个运算符为*,先执⾏2*3=6,第⼆个运算符为‘+’,执⾏1+6=7。
⼆ .表达式求值的过程:将算术表达式转换成后缀表达式,然后对后缀表达式求值。
1.将算术表达式转换为后缀表达式。
(1)从左到右⼀次扫描中缀表达式的每⼀个字符,如果是字符串,直接写⼊后缀表达式。
(2)如果遇到的是' ( ',则压⼊操作符栈,遇到‘(’时,将栈中的元素放到后缀表达式中,直达栈顶元素为'('时,将栈顶元素'('删除,不需要⼊栈。
(3)如果遇到的是操作符,则将操作符和操作符栈顶元素⽐较。
:如果a[i]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级:否则⼊栈。
(4)重复上述步骤,知道中缀表达式的结束符标记“#”,转换结束。
我的代码:#include<bits/stdc++.h>using namespace std;stack<char>f;//操作符栈stack<double>s;//操作数栈bool flag;int prior(char ch)//运算符的优先级{switch(ch){case'+':case'-':return 1;case'*':case'%':case'/':return 2;default:return 0;//括号}}string trans(string a){while(!f.empty()) f.pop();f.push('#');string ret="";//保存中缀表达式int len=a.size(),i=0;while(i<len){if(a[i]==' '||a[i]=='=')//??{i++;continue;}else if(a[i]=='(')f.push(a[i++]);else if(a[i]==')'){while(f.top()!='('){ret+=f.top();ret+=' ';f.pop();}f.pop();//(出栈i++;}else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/'||a[i]=='%'){while(prior(f.top())>=prior(a[i]))//如果a[]的运算符的优先级⼩于等于栈顶元素的优先级,退栈运算符并放到后缀表达式中,直到a[i]的运算符优先级⼤于栈顶运算符的优先级ret+=f.top();ret+=' ';f.pop();}f.push(a[i++]);}else{while((a[i]>='0'&&a[i]<='9')||a[i]=='.'){ret+=a[i++];}ret+=' ';}}while(f.top()!='#'){ret+=f.top();ret+=' ';f.pop();}ret+='=';return ret;}double cal(double a,double b,double ch)//计算{if(ch=='+') return a+b;if(ch=='-') return a-b;if(ch=='*') return a*b;if(ch=='%') return ((int)a%(int)b);if(ch=='/'){if(b!=0)return a/b;flag=true;return 0;}}double solve(string a)//后缀表达式计算{string t=trans(a);while(!s.empty()) s.pop();flag=false;int len=t.length(),i=0;while(i<len){if(t[i]==' '||t[i]=='='){i++;continue;}else if(t[i]=='+'||t[i]=='-'||t[i]=='*'||t[i]=='/'||t[i]=='%') {double num1,num2;num1=s.top();s.pop();num2=s.top();s.pop();s.push(cal(num1,num2,t[i]));i++;}else{double x=0;while(t[i]>='0'&&t[i]<='9'){x=x*10+t[i]-'0';i++;}if(t[i]=='.'){double k=10.0,y=0;i++;while(t[i]>='0'&&t[i]<='9'){y+=((t[i]-'0')/k);i++;k*=10;;}x+=y;}s.push(x);}}return s.top();}int main(){int num;scanf("%d",&num);while(num--){cin>>a;// cout<<e.trans(a)<<endl;//将中缀表达式装换为后缀表达式 cout<<solve(a)<<endl;}return 0;}。
数据结构课程设计---用两种方式实现表达式自动计算

一、设计思想(一)中缀转后缀的设计思想设计一个能实现表达式自动求值计算,算术表达式由操作数、算符和括号组成。
由于运算符的优先级不同还要考虑括号。
所以表达式不可能一直的从左到右进行,所以就借助栈来实现这个表达式的求值。
首先要把算术表达式变换成与之等值的无括号表达式,也就是中缀转后缀,它也是这个算法的关键。
设计两个栈,一个为字符型的,存放运算符,用以将算术表达式变成无括号的表达式;另一个浮点型的,存放操作数,用以对无符号的表达式进行求值。
我们要假设运算符的优先级:( ) , * /, + - 。
首先将一左括号‘(’入栈,作为栈底元素;接着从左到右对算术表达式进行扫描。
每次读一位,若遇到左括号‘(’,则进栈;若遇到的是操作数,则立即输出;若又遇到运算符,如果它的优先级比栈顶元素的优先级数高的话,则直接进栈,否则输出栈顶元素,直到新的栈顶元素的优先级数比它低的,然后将它压栈;若遇到是右括号‘)’,则将栈顶的运算符输出,直到栈顶的元素为‘(’,然后,左右括号互相底消;到设计的结束标志的时候表示表达式已经扫描完毕,表达式已经全部输入,将栈中的运算符全部输出,删除栈底的左括号。
以上完成了中缀表达式转后缀表达式,输出无括号的后缀表达式。
读后缀表达式,若遇数值,操作数进栈;若遇运算符,让操作数栈的栈顶和次栈顶依次出栈并与此运算符进行运算,运算结果入操作数栈;重复这个步骤,直到遇到结束标志,则此时栈中的结果便是所求的后缀表达式的值,接着输出结果。
以上就是设计这个算法的主要的思想。
(二) 直接计算的设计思想直接计算其实跟上一个相似,它是在上面扫两遍的思想进行修改的得来。
首先,要建立两个栈,一个为字符型的,存放运算符,另一个浮点型的,存放操作数,我们开始对表达式进行扫描。
首先要确定运算符的优先级:(、)、*、/、+、-。
如果扫描到的是数字符号,把它们转换成浮点型数据或其他可运算的数据类型,存入操作数栈中。
如果扫描到的是运算符号,第一个运算符进栈,遇到‘(’存入运算符栈中,我们按照第一种算法的方法将表达式依次扫描。
数据结构计算器(包括中缀转换后缀)课程设计报告

课程设计报告题目:计算表达式的值1.问题描述对于给定的一个表达式,表达式中可以包括常数、算术运行符(“+”、“-”、“*”、“/”)和括号,编写程序计算表达式的值。
基本要求:从键盘输入一个正确的中缀表达式,将中缀表达式转换为对应的后缀表达式,并计算后缀表达式的值。
对于表达式中的简单错误,能够给出提示,并给出错误信息;表达式中可以包括单个字母表示的变量。
测试数据:任意选取一个符合题目要求的表达式。
提高要求:(1)能够处理多种操作符。
(2)实现包含简单运算的计算器。
(3)实现一个包含简单运算和函数运算的计算器。
2.需求分析(1)软件的基本功能本软件实在win32工程下实现的带有界面和图标的功能较为齐全的计算器。
此计算器分三个方面进行计算,分别为数值表达式的计算,字母表达式的计算和函数计算。
可由键盘或用鼠标点击按键输入带有数字或字母的中缀表达式,程序可以将输入的带有数字或字母的中缀表达式转换成对应的后缀表达式,并计算只含有数字的后缀表达式的值。
本软件支持含小数、多位数等多种操作数的处理,可以计算含加、减、乘、除、百分号、求余、求幂,求阶乘,求三角函数的值等多种运算符和函数的表达式(2)输入/输出形式用户可通过打开图标弹出来的计算器界面任意点击操作。
对于在输入时发生的简单错误,软件通过弹出对话框给出提示并且在提示错误的同时自动将用户的出错输入略去转化成正确的表达式进行计算,用户也可选择清楚操作然后重新输入a.对于数值和函数表达式软件会输出其表达式的后缀表达式和计算结果并保留六位小数;b.对于字母表达式因字母无法进行数值运算,软件仅输出其后缀表达式的值;清楚按钮可以清楚有已经输入或输出的数据从头计算;软件窗口可实现最小化。
并且输入编辑框可进行修改,复制,粘贴等操作,但后缀表达式和求值结果的编辑框中的内容不可修改,只能执行复制操作。
(3)测试数据要求用户可以输入一个符合要求的中缀表达式,也可以输入一个包含简单错误的表达式。
表达式求值问题数据结构

《数据结构》课程设计报告书课程题目:表达式求值问题一.需求分析(1)以字符序列的形式从终端输入语法正确的不含变量的整数表达式,将该中缀表达式转换为后缀表达式。
(2)实现对后缀表达式的求值。
(3)演示在求值过程中运算符栈,操作数栈,输入字符和主要操作的变化过程。
二.概要设计表达式求值的算法分为两步进行:首先将中缀表达式转换为后缀表达式,再求后缀表达式的值。
(1)将中缀表达式转换为后缀表达式,对于字符串形式的合法的中缀表达式,“(”的运算优先级最高,“*”次之,“+”,“—”最低,同级运算符从左到右按顺序运算。
转化过程算法描述如下:从左到右对中缀表达式进行扫描,每次处理一个字符。
若遇到左括号入栈。
如遇到数字,原样输出。
若遇到运算符,如果它的优先级比栈顶元素优先级高,则直接入栈,否则栈顶元素出栈,直到新栈顶数据元素的优先级比它低,然后将它直接入栈。
重复以上步骤,直到表达式结束。
若表达式已全部结束,将栈顶元素全部出栈。
(2)后缀表达式求值算法描述如下:从左到右对后缀表达式进行扫描,每次处理一个字符。
若遇到数字,转化为整数,入栈。
若遇到运算符,出栈两个值进行运算,运算结果再入栈。
重复以上步骤,直到表达式结束,栈中最后一个数据元素就是所求表达式的结果。
三.详细设计#include<stdio.h>#include<stdlib.h>#define TRUE 1#define FALSE 0#define MAXNUM 100typedef int DataType;struct SeqStack{ DataType s[MAXNUM];int t;};typedef struct SeqStack *PSeqStack;PSeqStack createEmptyStack_seq(){PSeqStack pastack;pastack = (PSeqStack)malloc(sizeof(struct SeqStack)); if (pastack == NULL)printf("Out of space!!\n");elsepastack->t = -1;return pastack;} int isEmptyStack_seq(PSeqStack pastack){return pastack->t == -1;} void push_seq(PSeqStack pastack, DataType x){if (pastack->t >= MAXNUM - 1)printf("Overflow!\n");else{pastack->t = pastack->t + 1;pastack->s[pastack->t] = x;}} void pop_seq(PSeqStack pastack){if (pastack->t == -1)printf("Underflow!\n");elsepastack->t = pastack->t - 1;} DataType top_seq(PSeqStack pastack){return pastack->s[pastack->t];} int infixtoSuffix(const char * infix, char * suffix){ /*将中缀表达式转换为后缀表达式,顺利转换返回true,若转换过程中发现中缀表达式非法则返回false*/int state_int = FALSE;/*state_int记录状态,等于true表示刚读入的是数字字符,等于false表示刚读入的不是数字字符,设置这个变量是为了在每输出一个整数后输出一个空格,以免连续输出的两个整数混在一起。
数据结构课程设计-表达式求值【完整版】

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、算法:建立两个不同类型得空栈,先把一个‘#’压入运算符栈。
实验二 后缀表达式求值

韶关学院
学生实验报告册
实验课程名称:数据结构与算法
实验项目名称:实验二后缀表达式求值
实验类型(打√):(基础、综合、设计√)
院系:计算机科学学院专业:计算机科学技术姓名:*** 学号:*****
指导老师:***
韶关学院教务处编制
一、实验预习报告内容
二、实验原始(数据)记录
实验时间:2011 年9 月21 日(星期三第7,8 节)
实验同组人:
【程序运行结果】
通过分析输入数据和运行结果,证明程序顺利完成实验内容和要求。
指导教师
批阅及签名签名:年月日
三、实验报告内容
2011年9 月21 日
注:1、如有个别实验的实验报告内容多,实验报告册页面不够写,或有识图,画图要求的,学生应根据实验指导老师要求另附相同规格的纸张并粘贴在相应的“实验报告册”中。
2、实验报告册属教学运行材料,院系(中心)应按有关规定归档保管。
数据结构表达式求值实验报告-无删减范文

数据结构表达式求值实验报告数据结构表达式求值实验报告1. 引言表达式求值是计算机科学中的一个重要问题,也是数据结构的一个经典应用。
通过将中缀表达式转换为后缀表达式,并利用栈这一数据结构,可以实现对表达式的有效求值。
本实验旨在探究数据结构在表达式求值中的应用。
2. 实验内容本实验中,我们将实现一个表达式求值的程序。
具体步骤如下:1. 将中缀表达式转换为后缀表达式。
2. 使用栈来求解后缀表达式。
3. 算法原理3.1 中缀表达式转后缀表达式中缀表达式是我们常见的数学表达式,如 2 + 3 4。
而后缀表达式是将操作符放在操作数后面的表达式,上述中缀表达式的后缀表达式为 2 3 4 +。
中缀表达式到后缀表达式的转换可以通过以下步骤完成:1. 初始化一个栈和一个输出队列。
2. 从左到右遍历中缀表达式的每个字符。
3. 如果当前字符是数字,将其加入输出队列。
4. 如果当前字符是左括号,将其压入栈。
5. 如果当前字符是右括号,将栈中的操作符依次弹出并加入输出队列,直到遇到左括号为止。
6. 如果当前字符是操作符,将其与栈顶操作符进行比较:1. 如果栈为空,或者栈顶操作符为左括号,直接将当前操作符压入栈。
2. 否则,比较当前操作符与栈顶操作符的优先级,如果当前操作符的优先级较低,将栈顶操作符弹出并加入输出队列,然后将当前操作符压入栈。
3. 如果当前操作符的优先级大于等于栈顶操作符的优先级,则直接将当前操作符压入栈。
7. 遍历完中缀表达式后,将栈中的操作符依次弹出并加入输出队列。
3.2 后缀表达式求值通过将中缀表达式转换为后缀表达式,我们可以利用栈来对后缀表达式进行求值。
具体求值操作如下:1. 初始化一个栈。
2. 从左到右遍历后缀表达式的每个字符。
3. 如果当前字符是数字,将其加入栈。
4. 如果当前字符是操作符,从栈中弹出两个数字,进行相应的运算,然后将结果加入栈。
5. 遍历完后缀表达式后,栈中的元素即为最终的结果。
4. 实验结果我们用中缀表达式\。
C语言实现中缀、后缀、前缀表达式_相互转化并求值

1.问题描述(1)表达式求值问题表达式是数据运算的基本形式。
人们的书写习惯是中缀式,如:11+22*(7-4)/3。
中缀式的计算按运算符的优先级及括号优先的原则,相同级别从左到右进行计算。
表达式还有后缀式(如:22 7 4 - * 3 / 11 +)和前缀式(如:+ 11 / * 22 – 7 4 3)。
后缀表达式和前缀表达式中没有括号,给计算带来方便。
如后缀式计算时按运算符出现的先后进行计算。
本设计的主要任务是进行表达式形式的转换及不同形式的表达式计算。
2.数据结构设计(1)表达式求值问题由于表达式中有字符与数字两种类型,故定义结点一个标志域data,标志结点存储的为字符data=2还是数字data=1,再寻找结点中对应的存储位置,读取数字域data1,字符域data2。
而在前缀表达式时,存在表达式逆序,因表达式类型不统一,用栈逆序极不方便,选择构建双向链表,存储表达式。
typedef struct Node //定义存储中缀表达式的结点类型{int data;int data1;char data2;struct Node *next;}Lnode;typedef struct Node2 //定义存储前缀表达式的结点类型{int data;int data1;char data2;struct Node2 *next;struct Node2 *prior;}Lnode2;3.运行、测试与分析(1)表达式求值问题(1)按提示输入中缀表达式,如图1.1所示。
如输入中缀表达式不正确,提示输入有误,如图1.2,1.3所示。
图1.1图1.2图1.3(2)选择表达式转换并求值方式。
按“1”选择中缀表达式求值,如图1.4所示。
图1.4(3)按“2”选择中缀表达式转变为后缀表达式并求值,如图1.5所示。
图1.5(4)按“3”选择中缀表达式转变为前缀表达式并求值,如图1.6所示。
图1.6附录:源代码(1)表达式求值问题#include<stdio.h>#include<stdlib.h>#define MAXNUM 100typedef struct Node //定义存储中缀表达式的结点类型{int data;int data1;char data2;struct Node *next;}Lnode;typedef struct Node2 //定义存储前缀表达式的结点类型{int data;int data1;char data2;struct Node2 *next;struct Node2 *prior;}Lnode2;typedef int selemtype1; //定义运算数栈的结点typedef struct //定义运算数栈的类型{selemtype1 *base;selemtype1 *top;}sqstack1;void InitStack1(sqstack1 &s) //新建一个空运算数栈{s.base=(selemtype1 *)malloc(MAXNUM*sizeof(selemtype1)); s.top=s.base;if(!s.base) printf("出错:申请空间失败!\n");}void Push1(sqstack1 &s,selemtype1 &e) //运算数栈,入栈:插入元素e为新的栈顶元素{ if(s.top-s.base>=MAXNUM)printf("出错:表达式过长!1\n");*s.top++ =e;}void GetTop1(sqstack1 s,selemtype1 &e) //运算数栈,用e返回栈顶元素{e=*(s.top-1);}void Popopnd1(sqstack1 &s,selemtype1 &e) //运算数栈,退栈:删除栈顶元素,并用e返回其值{e=*--s.top;}int stackempy1(sqstack1 s) //运算数栈,若为空栈返回1,否则返回0{if(s.top==s.base) return 1;else return 0;}typedef char selemtype2; //定义运算符栈的结点类型typedef struct //定义运算符栈类型{selemtype2 *base;selemtype2 *top;}sqstack2;void InitStack2(sqstack2 &s) //新建一个空运算符栈{s.base=(selemtype2 *)malloc(MAXNUM*sizeof(selemtype2));s.top=s.base;if(!s.base) printf("出错:申请空间失败!\n");}void Push2(sqstack2 &s,selemtype2 &e) //运算符栈,入栈:插入元素e为新的栈顶元素{ if(s.top-s.base>=MAXNUM)printf("出错:表达式过长!2\n");*s.top++ =e;}void GetTop2(sqstack2 s,selemtype2 &e) //运算符栈,用e返回栈顶元素{e=*(s.top-1);}void Popopnd2(sqstack2 &s,selemtype2 &e) //运算符栈,退栈:删除栈顶元素,并用e返回其值{e=*--s.top;}int stackempy2(sqstack2 s) //运算符栈,若为空栈返回1,否则返回0{if(s.top==s.base) return 1;else return 0;}void priority(char c,int &i) //确定运算符优先级{if (c=='*'||c=='/'||c=='%') i=2 ;else if (c=='+'||c=='-') i=1 ;else i=0;}int compare(char a,char b) //比较栈顶元素运算符与外部运算符优先级大小,外部优先级大则返回1,反之返回0{int in,out;priority(a,in);priority(b,out);if(out>in) return 1;else return 0;}void Operat(sqstack1 &OPND,sqstack2 &OPTR){int num1,num2,num;char c;Popopnd1(OPND,num2);Popopnd1(OPND,num1);Popopnd2(OPTR,c);switch(c){case '+':num=num1+num2;break;case '-':num=num1-num2;break;case '*':num=num1*num2;break;case '/':num=num1/num2;break;case '%':num=num1%num2;break;}Push1(OPND,num);}void Operatqianzhui(sqstack1 &OPND,sqstack2 &OPTR){int num1,num2,num;char c;Popopnd1(OPND,num1);Popopnd1(OPND,num2);Popopnd2(OPTR,c);switch(c){case '+':num=num1+num2;break;case '-':num=num1-num2;break;case '*':num=num1*num2;break;case '/':num=num1/num2;break;case '%':num=num1%num2;break;}Push1(OPND,num);}void houzhuiqiuzhi(Lnode *p,int &e) //后缀表达式求值{sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n;char c;p=p->next;InitStack1(OPND);InitStack2(OPTR);while(p){switch(p->data){case 1:n=p->data1;Push1(OPND,n);break;case 2:c=p->data2;Push2(OPTR,c);Operat(OPND,OPTR);break;default:printf("结点有误");break;}p=p->next;}Popopnd1(OPND,n);e=n;}void zhongzhui(Lnode *p) //中缀表达式求值{sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n;char c,c2;Lnode *first;first=p;p=p->next;InitStack1(OPND);InitStack2(OPTR);while(!stackempy2(OPTR)||p){while(p){switch(p->data){case 1:n=p->data1;Push1(OPND,n);break;case 2:c=p->data2;if(stackempy2(OPTR)) Push2(OPTR,c);else { switch(c){case '(': Push2(OPTR,c);break;case ')': GetTop2(OPTR,c2);while(c2!='('){Operat(OPND,OPTR);GetTop2(OPTR,c2);}Popopnd2(OPTR,c2);break;default: GetTop2(OPTR,c2);if(compare(c2,c)) Push2(OPTR,c); else { Operat(OPND,OPTR);Push2(OPTR,c);}break;}}break;default: printf("结点有误");break;}p=p->next;}while(!stackempy2(OPTR))Operat(OPND,OPTR);}Popopnd1(OPND,n);p=first->next;while(p){if(p->data==1) printf("%d ",p->data1);if(p->data==2) printf("%c",p->data2);p=p->next;}printf("=%d ",n);}void houzhui(Lnode *p) //中缀表达式转化为后缀表达式{sqstack2 OPTR; //运算符栈Lnode *r,*q,*head;int n;char c,c2;InitStack2(OPTR);p=p->next;q=(Lnode*)malloc(sizeof(struct Node));head=q;while(p){ switch(p->data){case 1:n=p->data1;r=(Lnode*)malloc(sizeof(struct Node));q->next=r;q=q->next;q->data=1;q->data1=n;break;case 2:c=p->data2;if(stackempy2(OPTR)) Push2(OPTR,c);else { switch(c){ case '(': Push2(OPTR,c);break;case ')': Popopnd2(OPTR,c2);while(c2!='('){ r=(Lnode*)malloc(sizeof(struct Node));q->next=r;q=q->next;q->data=2;q->data2=c2;Popopnd2(OPTR,c2);}break;default: GetTop2(OPTR,c2);while(!compare(c2,c)){ Popopnd2(OPTR,c2);r=(Lnode*)malloc(sizeof(struct Node));q->next=r;q=q->next;q->data=2;q->data2=c2;GetTop2(OPTR,c2);}Push2(OPTR,c);break;}}break;default: printf("结点有误");break;}p=p->next;}while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2);r=(Lnode*)malloc(sizeof(struct Node));q->next=r;q=q->next;q->data=2;q->data2=c2;}q->next=NULL;q=head->next;while(q){if(q->data==1) printf("%d ",q->data1);if(q->data==2) printf("%c",q->data2);q=q->next;}houzhuiqiuzhi(head,n);printf("=%d ",n);}void qianzhuiqiuzhi(Lnode2 *p,int &e) //前缀表达式求值{sqstack1 OPND; //运算数栈sqstack2 OPTR; //运算符栈int n;char c;Lnode2 *head;head=p;p=p->next;InitStack1(OPND);InitStack2(OPTR);while(p!=head){switch(p->data){case 1:n=p->data1;Push1(OPND,n);break;case 2:c=p->data2;Push2(OPTR,c);Operatqianzhui(OPND,OPTR); break;default:printf("结点有误");break;}p=p->next;}Popopnd1(OPND,n);e=n;}void qianzhui(Lnode *p) //中缀表达式转化为前缀表达式{sqstack2 OPTR; //运算符栈InitStack2(OPTR);int n;char c,c2;Lnode *first;Lnode2 *q,*head,*r,*head2,*s;first=p;p=p->next;q=(Lnode2*)malloc(sizeof(struct Node2)); //建立存中缀表达式的双向循环链表head=q;while(p){r=(Lnode2*)malloc(sizeof(struct Node2));q->next=r;r->prior=q;q=q->next;q->data=p->data;q->data1=p->data1;q->data2=p->data2;p=p->next;}q->next=head;head->prior=q;s=(Lnode2*)malloc(sizeof(struct Node2)); //建立存前缀表达式的双向循环链表head2=s;while(q!=head){switch(q->data){case 1:n=q->data1;r=(Lnode2*)malloc(sizeof(struct Node2));s->next=r;r->prior=s;s=s->next;s->data=1;s->data1=n;break;case 2:c=q->data2;if(stackempy2(OPTR)) Push2(OPTR,c);else{ GetTop2(OPTR,c2);if(c2==')') Push2(OPTR,c);else{ switch(c){ case ')':Push2(OPTR,c);break;case '(': Popopnd2(OPTR,c2);while(c2!=')'){ r=(Lnode2*)malloc(sizeof(struct Node2));s->next=r;r->prior=s;s=s->next;s->data=2;s->data2=c2;Popopnd2(OPTR,c2);}break;default: GetTop2(OPTR,c2);while(!compare(c2,c)){ Popopnd2(OPTR,c2);r=(Lnode2*)malloc(sizeof(struct Node2));s->next=r;r->prior=s;s=s->next;s->data=2;s->data2=c2;GetTop2(OPTR,c2);}Push2(OPTR,c);break;}}}break;default:printf("结点有误");break;}q=q->prior;}while(!stackempy2(OPTR)){ Popopnd2(OPTR,c2);r=(Lnode2*)malloc(sizeof(struct Node2));s->next=r;r->prior=s;s=s->next;s->data=2;s->data2=c2;}s->next=head2;head2->prior=s;while(s!=head2){if(s->data==1) printf("%d ",s->data1); if(s->data==2) printf("%c",s->data2); s=s->prior;}qianzhuiqiuzhi(head2,n);printf("=%d ",n);}int main(){ char n[10];char c;int i,j,k,a,b,z,y,e;Lnode *p,*q,*first;i=0;e=1;a=0;b=1;z=0;y=0;p=(Lnode*)malloc(sizeof(struct Node));first=p;printf("请输入中缀表达式");do{ c = getchar();if('0'<=c&&c<='9'){ n[i]=c;i++;}else{ switch (c){ case '+':case '-':case '*':case '/':case '%':case '(':case ')':case '\n':{ if(n[0]>'0'&&n[0]<='9'){ q=(Lnode*)malloc(sizeof(struct Node)); p->next=q;p=p->next;for(k=0;k<i;k++){ for(j=0;j<=i-k-2;j++)e=e*10;a=a+(n[k]-'0')*e;e=1;n[k]='0';}p->data=1;p->data1=a;i=0;a=0;}if(c!='\n'){ if(p->data==2){ if(p->data2!=')'&&c!='(')b=0;}q=(Lnode*)malloc(sizeof(struct Node));p->next=q;p=p->next;p->data=2;p->data2=c;if(c=='(') z++;if(c==')') y++;}}default:if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='%'&&c!='\n'&&c!='('&&c!=')') b=0;}}}while (c != '\n');if(z!=y) b=0;p->next=NULL;if(b==0)printf("输入中缀表达式有误");else{printf("输入1中缀表达式求值,输入2后缀表达式求值,输入3前缀表达式求值");scanf("%d",&b);if(b==1) zhongzhui(first);if(b==2) houzhui(first);if(b==3) qianzhui(first);}return 1;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cout<<"┃**************★4输入‘t’表示tan★**************┃";
cout<<"┃**************★5输入‘S’表示arcsin★**************┃";
return;
case 'T':stack.push(atan(op2));
return;
}
if (stack.isEmptyStack())
{
out<<"(没有足够的数)";
expressionOk=false;
}
else
{
op1=stack.top();
stack.pop();
switch (ch)
stackTop++;
}
else
{
cout<<"full!!";
}
}
template<class Type>
Type stackType<Type>::top() const//栈顶元素
{
assert (stackTop!=0);
return list[stackTop-1];
}
template<class Type>
void initializeStack(); //构造函数
bool isEmptyStack() const;
bool isFullStack() const;
void destroyStack();
void push(const Type& newItem);
Type top() const;
void pop();
#include<iostream>
#include<cassert>
using namespace std;
template<class Type> //用模板实现的链式结构堆栈类
class stackType
{
public:
const stackType<Type> & operator=(const stackType<Type>&);
cout<<"┃**************★9输入‘^’表示x的y次幂★**************┃";
cout<<"┃**************★10输入数字前请加“`”符号★**************┃";
cout<<"┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫";
{
stackTop=0;
}
template<class Type>
bool stackType<Type>::isEmptyStack() const //判断栈空
{
return (stackTop==0);
}
template<class Type>
bool stackType<Type>::isFullStack() const //判断栈满
{
maxStackSize=stackSize;
stackTop=0;
list=new Type[maxStackSize];
assert(list!=NULL);
}
}
template<class Type>
stackType<Type>::~stackType() //释放栈
{
delete [] list;
{
out<<"(没有足够的数)";
expressionOk=false;
}
else
{
op2=stack.top();
stack.pop();
switch (ch)
{
case '~':stack.push(sqrt(op2));
return;
case 's':stack.push(sin(op2));
三、设计内容和要求
四、 运用栈模板在求值过程顺序扫描后缀表达式,每次遇到操作数便将它压入堆栈;遇到运算符,则从栈中弹出两个操作数进行计算,然后再把结果压入堆栈,等到扫描结束时,输出结果,有加减乘除、平方根、sin、cos、tan、arcsin、arcos、arctan、取余、幂运算等等算术。
五、 程序结构
五、运行图
参考文献:
刘振鹏编,数据结构(第二版),北京铁道出版社,2007.;
谭浩强编,C++程序设计,北京,清华大学出版社,2004.;
徐晓凯编,数据结构实用教程,第二版,北京,清华大学出版社。
附录:源文件
头文件myStack.h:
#ifndef H_StackType
#define H_StackType
stackType(int stackSize=100);
stackType(const stackType<Type>& otherStack);
~stackType();
private:
int maxStackSize;
int stackTop;
Type *list;
void copyStack(const stackType<Type>& otherStack);
return;
case 'c':stack.push(cos(op2));
return;
case 't':stack.push(tan(op2));
return;
case 'S':stack.push(asin(op2));
return;
case 'C':stack.push(acos(op2));
cout<<"┃**********★★★★★★★★★★★★★★★★★**********┃";
cout<<"┃**************☆感谢您使用后缀表达式求值程序☆**************┃";
cout<<"┃**************☆用户说明☆**************┃";
cout<<"┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫";
long double num,result;
bool expressionOk;
char ch;
stackType<long double> stack(100);
cout<<"请输入后缀表达式:"<<en#39;q' && ch!='Q')
{
stack.initializeStack();
}
template<class Type>
stackType<Type>::stackType(const stackType<Type>& otherStack)
{
list=NULL;
copyStack(otherStack);
}
template<class Type>
const stackType<Type>& stackType<Type>::operator=
{
delete [] list;
maxStackSize=otherStack.maxStackSize;
stackTop=otherStack.stackTop;
list=new Type[maxStackSize];
assert(list!=NULL);
for (int j=0;j<stackSize;j++)
数据结构课程设计
后缀表达式求值
题目:
后缀表达式求值
指导老师:
高攀
姓名:
顾力雄
学院:
信息科学与技术学院
专业:
计算机科学与技术专业
班级:
计科2008级(1)班
学号:
2008082258
时间:
2009年3月28日
课程设计报告
一、题目:后缀表达式求值;
二、设计目的
1、掌握类模板的应用
2、掌握栈的操作
3、 掌握
else
{
out<<"(用0除)";
expressionOk=false;
}
break;
case '^':stack.push(pow(op1,op2));
break;
case '%':stack.push(int(op1) % int(op2));
break;
default:out<<"(错误的运算符)";
cout<<"┃**************★6输入‘C’表示arccos★**************┃";
cout<<"┃**************★7输入‘t’表示arctan★**************┃";