将中缀表达式转换为后缀表达式并计算
中缀表达式转换为后缀表达式

中缀表达式转换为后缀表达式课程设计任务:中缀表达式转后缀表达式,并求值。
课程设计思路:把中缀表达式转换为后缀表达式算法的基本思路是从头到尾地扫描中缀表达式中的每个字符,对于不同类型的字符按不情况进行处理。
若遇到的是空格则认为是分隔符,不需要进行处理;若遇到的是数字或小数点,则直接写入到c2中;若遇到的是左括号,则应把它压入到运算符栈中,待以它开始的括号内的表达式转换完毕后再出栈;若遇到的是右括号,则表明括号内的中缀表达式已经扫描完毕,把从栈底直到保存着的对应左括号之间的运算符依次退栈并写入c2串中;若遇到的是运算符,当该运算符的优先级大于栈顶运算符的优先级(加减运算符的优先级设定为1,乘除运算符的优先级设定为2,在栈中保存的特殊运算符’(’的优先级设定为0)时,表明该运算符的后一个运算对象还没有被扫描并放入到c2串中,应把它暂存于运算符栈中,待它的后一个运算对象从c1串中读出并写入到c2串中后,再另其出栈并写入c2串中;若遇到的运算符的优先级小于等于栈顶运算符的优先级,这表明栈顶运算符的两个运算对象已经被保存到c2串中,应将栈顶运算符退栈并写入到c2串中,对于新的栈顶运算符仍继续进行比较和处理,直到被处理的运算符的优先级大于栈顶运算符的优先级为止,然后另该运算符进栈即可。
按照以上过程扫描到中缀表达式结束符时,把栈中剩余的运算符依次退栈并写入到后缀表达式中,再向c2写入表达式结束符和字符串结束符’\0’,整个转换过程就处理完毕,在c2中就得到了转换成的后缀表达式。
课程设计流程:设中缀算术表达式为:10+(18+9*3)/15-6,则转换过程如下:(1)开始时存放后缀表达式的字符串c2为空:(2)当扫描到左括号时,c2和栈中的数据变化如下:1 0((3)当扫描到数值3时,c2和栈中的数据变化为:1 0 1 8 9 3( + *(4)当扫描到右括号时,c2和栈变为:1 0 1 8 9 3 * +(5)当扫描到的数值15时,c2和栈又变为:1 0 1 8 9 3 * + 1 5/(6)当扫描到‘’字符时,c2和栈为:1 0 1 8 9 3 * + 1 5 / + 6-7)当整个处理过程结束后,栈为空,c2为:1 0 1 8 9 3 * + 1 5 / + 6 -算法基本思想:从头到尾扫描中缀表达式,对不同类型的字符按不同情况处理;1、如果是数字则直接放入后缀表达式数组;2、如果是左括号则直接入栈;3、如果是右括号,则把从栈顶直到对应左括号之间的运算符依次退栈,并清除对应的左括号;4、对于运算符,如果该运算符的优先级大于栈顶优先级,则直接入栈,若该运算符的优先级小于等于栈顶优先级,则先把栈顶运算符出栈,写入后缀表达式数组,然后再入栈;5、扫描完成后,取出栈中所有运算符,写入后缀表达式数组。
中缀转后缀表达式计算报告

目录一、设计思想 (01)二、算法流程图 (02)三、源代码 (04)四、运行结果 (14)五、遇到的问题及解决 (16)六、心得体会 (16)一、设计思想(1)中缀表达式转后缀表达式并计算创建一个数组存储输入的计算表达式。
另创建一个数组储存将要生成的后缀表达式。
创建一个栈储存操作符。
对已存储的表达式数组扫描。
判断当前节点,如果是操作数或’.’,直接加入后缀表达式中,如果是操作符,则比较前一个操作符与当前操作符的优先级。
如果前一个操作符的优先级较高,则将前一个操作符加入后缀表达式中,否则将操作符压入操作符栈。
如果遇到左括号’(’,直接入栈;如果遇到右括号’)’,则在操作符栈中反向搜索,直到遇到匹配的左括号为止,将中间的操作符依次加到后缀表达式中。
当执行完以上操作,发现栈中仍有剩余操作符,则将操作符依次加到后缀表达式中。
此时中缀表达式已经转换成了后缀表达式。
对后缀表达式进行计算。
如果后缀表达式为大于0小于9的字符,则将它转换成浮点型数据并存入数栈中。
如果遇到操作符,则从数栈中提取两个数,进行相应的运算。
依次进行下去,当没有运算符是,运算结束得到最后的结果。
(2)直接表达式求值创建一个数组存储输入的计算表达式。
创建两个栈,一个字符型的栈,一个双精度型的栈。
分别用来存储字符和数。
对已存储的表达式数组扫描。
判断当前节点,如果是操作数和’.’,将字符型的操作数转换为浮点型的数后存入操作数栈。
如果是操作符则判断操作符的优先级。
如果字符栈中已存储符号的优先级小于要存入的字符的优先级,则直接让字符入操作符栈。
如果字符栈中已存储符号的优先级大于或等于要存入的字符的优先级,则取出操作符栈中的一个字符和操作数栈中的两个数进行计算,然后将结果存入操作数栈中,同上进行下去,直到字符栈中已存储符号的优先级小于要存入的字符的优先级时,将操作符存入操作符栈中。
当遇到左括号’(’,将左括号直接存入操作符栈中。
当遇到右括号’)’,则在操作符栈中反向搜索,并且每搜到一个字符就在操作数栈中取两个数进行相应的计算。
逻辑表达式短路求值后缀表达式

逻辑表达式短路求值后缀表达式逻辑表达式短路求值后缀表达式的过程如下:1. 将中缀逻辑表达式转换为后缀表达式。
这个过程可以使用运算符优先级和括号来确定运算符的顺序。
2. 执行后缀表达式的求值过程。
从左到右扫描后缀表达式:- 如果遇到操作数,将其压入栈中。
- 如果遇到操作符,从栈中弹出相应数量的操作数进行运算,并将运算结果压入栈中。
- 重复上述步骤,直到扫描完后缀表达式。
3. 最终栈中剩下的元素就是整个逻辑表达式的求值结果。
例如,对于逻辑表达式 "A && B || C",其后缀表达式为 "A B&& C ||"。
假设 A = true,B = false,C = true,那么短路求值的过程如下:1. 将 A 和 B 压入栈中。
2. 遇到 "&&" 操作符,从栈中弹出 B(false),然后从栈中弹出 A(true)。
将 A && B 的结果(false)压入栈中。
3. 将 C 压入栈中。
4. 遇到 "||" 操作符,从栈中弹出 C(true),然后从栈中弹出A &&B 的结果(false)。
将 (A && B) ||C 的结果(true)压入栈中。
5. 栈中剩下的元素是最终的结果,即 (A && B) || C 的值为 true。
因此,逻辑表达式 "A && B || C" 的短路求值后缀表达式的结果为 true。
中缀转后缀并输出运算步骤

中缀转后缀并输出运算步骤从中缀表达式转换为后缀表达式的过程中,需要遵循一定的规则和算法。
下面将具体介绍中缀转后缀的步骤及其运算过程。
一、引言中缀表达式是我们日常生活中最常见的表达式形式,例如:2 + 3 * 4。
但是,对于计算机来说,中缀表达式并不方便进行计算,因此需要将其转换为后缀表达式。
后缀表达式也被称为逆波兰表达式,它的计算规则更加简单明了。
二、中缀转后缀的规则和算法1. 创建一个空的栈,用于存储运算符。
2. 从左到右遍历中缀表达式的每个元素。
3. 如果当前元素是操作数,则直接输出到后缀表达式。
4. 如果当前元素是左括号"(",则将其压入栈中。
5. 如果当前元素是右括号")",则将栈中的运算符依次弹出并输出到后缀表达式,直到遇到左括号为止。
注意:左括号不输出。
6. 如果当前元素是运算符,则判断栈顶运算符的优先级:- 若栈为空,则直接将当前运算符压入栈中。
- 若栈不为空,且当前运算符的优先级小于等于栈顶运算符的优先级,则将栈顶运算符弹出并输出到后缀表达式,直到栈为空或者栈顶运算符的优先级小于当前运算符。
- 将当前运算符压入栈中。
7. 遍历完中缀表达式后,如果栈中还有运算符,则依次弹出并输出到后缀表达式。
三、运算过程示例考虑中缀表达式:"2 + 3 * 4 - (5 + 6) / 7"1. 创建空栈和空后缀表达式。
2. 从左到右遍历中缀表达式的每个元素:- 遇到"2",为操作数,直接输出到后缀表达式。
- 遇到"+",为运算符,将其压入栈中。
- 遇到"3",为操作数,直接输出到后缀表达式。
- 遇到"*",为运算符,将其压入栈中。
- 遇到"4",为操作数,直接输出到后缀表达式。
- 遇到"-",为运算符,栈顶为"*",优先级高于"-",因此将"*"弹出并输出到后缀表达式,然后将"-"压入栈中。
中缀表达式得到后缀表达式(c++、python实现)

中缀表达式得到后缀表达式(c++、python实现)将中缀表达式转换为后缀表达式的算法思想如下: 从左往右开始扫描中缀表达式 遇到数字加⼊到后缀表达式 遇到运算符时: 1、若为‘(’,⼊栈 2、若为’)‘,把栈中的运算符依次加⼊后缀表达式,直到出现'(',’(‘出栈,退出该次循环 3、若除’(‘ 和 ‘)’,要⼊栈的运算符优先级⼤于等于栈顶的运算符的优先级,直接⼊栈,否者,栈顶运算符出栈,再次⽐较,直到出现优先级低的运算符,或者栈为空,退出 中缀表达式为空时,若栈不为空,栈中元素⼀直出栈,直到栈为空运算符 ( *,/ +,- )栈内优先级 1 5 3 6栈外优先级 6 4 2 1C++实现如下:#include <iostream>#include <algorithm>#include <string>#include <stack>#include <map>using namespace std;int main(){string s_mid="a+b-a*((c+d)/e-f)+g";string s_beh="";stack<char> stk;// stack<char> stk1;map<char,int> op;//利⽤map来实现运算符对应其优先级op['(']=0;op[')']=0;op['+']=1;op['-']=1;op['*']=2;op['/']=2;string::iterator it=s_mid.begin();;while(it!=s_mid.end()){if(op.count(*it))//判断该元素是否为运算符{if(*it==')')//情况2{while(stk.top()!='('){s_beh+=stk.top();stk.pop();}stk.pop();}else if(stk.empty()||*it=='('||op[*it]>op[stk.top()])//情况1、情况3{stk.push(*it);}else if(op[*it]<=op[stk.top()])//情况3{while(op[*it]<=op[stk.top()]&&(!stk.empty())){s_beh+=stk.top();stk.pop();if(stk.empty()) break;}stk.push(*it);}}else{s_beh+=*it;}it++;// cout<<s_beh<<'\t'; 输出每次结构// stk1=stk;// while(!stk1.empty()) 输出栈内情况// {// cout<<stk1.top();// stk1.pop();// }// cout<<endl;if(it==s_mid.end())//当中缀表达式输出完成,所有元素出栈 {while(!stk.empty()){s_beh+=stk.top();stk.pop();}break;}}cout<<s_beh<<endl;return0;}View Codepython实现如下:#-*- coding:utf-8 -*-if__name__=='__main__':s_mid='23/b+(c*d-e*f)/g's_beh=''d={'(':0,')':0,'+':1,'-':1,'*':2,'/':2};l=[]while(len(s_mid)):if s_mid[0] in d.keys():if s_mid[0]==')':while True:if l[len(l)-1]=='(':breakelse:s_beh+=l.pop()l.pop()elif len(l)==0 or s_mid[0]=='('or d[l[len(l)-1]]<d[s_mid[0]]: l.append(s_mid[0])elif d[l[len(l)-1]]>=d[s_mid[0]]:while d[l[len(l) - 1]] >= d[s_mid[0]]:s_beh+=l.pop()if len(l)==0:breakl.append(s_mid[0])else:s_beh+=s_mid[0]s_mid=s_mid[1:]if len(s_mid)==0:while len(l):s_beh += l.pop()print s_behView Code。
算法笔记--中缀表达式转后缀表达式后缀表达式计算

算法笔记--中缀表达式转后缀表达式后缀表达式计算中缀表达式转后缀表达式规则中缀表达式a + b*c + (d * e + f) * g,转换成后缀表达式则为a b c * + d e * f + g * +转换过程需要⽤到栈,具体过程如下:1 如果遇到操作数,我们就直接将其输出。
2 如果遇到操作符,则我们将其放⼊到栈中,遇到左括号时我们也将其放⼊栈中。
3 如果遇到⼀个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为⽌。
注意,左括号只弹出并不输出。
4 如果遇到任何其他的操作符,如+, *, (等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为⽌。
弹出完这些元素后,才将遇到的操作符压⼊到栈中。
有⼀点需要注意,只有在遇到 )的情况下我们才弹出( ,其他情况我们都不会弹出( 。
即:若操作符op的优先级⾼于栈顶操作符的优先级,则压⼊操作符栈若操作符op的优先级⼩于等于栈顶操作符的优先级,则将操作栈的操作符不断弹出到后缀表达式中,直到op的优先级⾼于栈顶操作符的优先级5 如果我们读到了输⼊的末尾,则将栈中所有元素依次弹出。
实例a +b *c + (d *e + f) * g1. ⾸先读到a,直接输出。
2. 读到“+”,将其放⼊到栈中。
3. 读到b,直接输出。
此时栈和输出的情况如下:4. 读到“*”,因为栈顶元素"+"优先级⽐" * " 低,所以将" * "直接压⼊栈中。
5. 读到c,直接输出。
此时栈和输出情况如下:6. 读到" + ",因为栈顶元素" * "的优先级⽐它⾼,所以弹出" * "并输出,同理,栈中下⼀个元素" + "优先级与读到的操作符" + "⼀样,所以也要弹出并输出。
然后再将读到的" + "压⼊栈中。
C语言下表达式的自动计算(两种方式)(报告+源代码)

一、设计思想第一种算法:将中缀表达式转为后缀表达式,然后通过后缀表达式计算出算术表达式的结果。
核心思想:第一步:中缀变后缀。
首先,我们做出一个统一的Node结构体,结构体内部包含四个属性,分别是操作符的字符‘op’,char类型;操作符的优先级‘level’,int 类型;数字的浮点数数值‘od’,float类型;Node的标识符,int类型。
然后,定义一个Node结构体类型的数组*listNode,这里的*listNode用的是全局变量,为了方便在得到后缀表达式后,不需再传递给计算的方法。
定义一个存放操作符的栈,遍历用户输入的算术表达式(不考虑错误情况),在遍历的过程中如果遇到数字,直接将数字存放在*listNode里面;如果遇到了操作符,则判断操作符栈目前是不是为空,如果为空,直接将遇到的操作符放入操作符栈中,如果操作符栈不为空,那么观察操作符栈中栈顶的操作符,然后再次判断当前遇到的操作符的优先级是不是比栈顶的操作符的优先级高,如果是,那么将当前的操作符入操作符栈;如果不是,那么将操作符栈的栈顶操作符取出,追加到*listNode中,然后继续观察栈顶操作符,直到当前的操作符的优先级比栈顶操作符的优先级高或者操作符栈为空时,将当前操作符入操作符栈。
如果遇到了左括号,那么定义其优先级为最低,然后直接将左括号入操作符栈。
如果遇到了右括号,那么开始从操作符栈中取出操作符追加到*listNode中,直到遇到了与之对应的左括号,然后将左括号和右括号一起销毁。
当遍历完成了算术表达式之后,这时判断操作符栈是否为空,如果不为空,那么从操作符栈中依次取出栈顶操作符追加到*listNode中,直到操作符栈为空,那么就代表我们将中缀表达式转变成为了后缀表达式。
第二步:通过得到的后缀表达式,计算算术表达式。
首先,定义一个数字栈用来存放数值。
然后,遍历*listNode中的每一个Node,如果Node是一个数字,那么就将数字入数字栈,如果Node是一个操作符,那么就从数字栈中依次取出栈顶的两个数字,然后根据操作符计算这两个数字,将得到的结果再次入数字栈,直到遍历*listNode完成,最终数字栈中会只剩下一个Node,那就是我们计算出算术表达式的结果,将结果返回给main 函数用来输出。
中缀表达式转后缀表达式并计算结果(c语言版)

中缀表达式转后缀表达式中缀表达式转后缀表达式的规则。
1.遇到操作数:直接输入到后缀表达式栈2.遇到运算符,直接入操作符栈3.遇到左括号:直接将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将操作符栈中的元素依次出栈,输出到后缀表达式栈。
以下是自己写的代码。
亲测没有问题。
(模拟一个计算器,可以带括号,中间可以空格,只支持整数输入,但是输出结果精确到小数后6位)#include "stdio.h"#define MAX_LEN 100typedef struct cal{unsigned char isOper;//是否是操作数1,操作符0.操作数double Num; //值。
或者是操作符的ASCII值}STRUCT_CAL;#define IS_NUM 0x00#define IS_OPER 0x01STRUCT_CAL stackCal[MAX_LEN];STRUCT_CAL stackCalBack[MAX_LEN];unsigned char topCal;char stackOper[MAX_LEN];unsigned char topOper;/****************************************************************** 堆栈初始化*****************************************************************/void stackInit(void){int i;for(i=0;i<MAX_LEN;i++){stackCal[i].isOper = 0;stackCal[i].Num = 0;stackOper[i] = 0;}topCal = topOper = 0;}/***************************************************************** * 返回堆栈的栈顶,返回后栈顶减一*****************************************************************/ STRUCT_CAL * stackCalPop(void){if(topCal == 0)return (STRUCT_CAL *)0;return stackCal+(--topCal);}/***************************************************************** * 计算表达式入栈*****************************************************************/void stackCalPush(double num, unsigned char isOper){if(topCal>=MAX_LEN)return;stackCal[topCal].Num = num;stackCal[topCal].isOper= isOper;topCal++;}/***************************************************************** * 操作符出栈*****************************************************************/char stackOperPop(void){if(topOper == 0)return 0;return stackOper[--topOper];}/****************************************************************** 操作符入栈*****************************************************************/void stackOperPush(char oper){if(topOper >=MAX_LEN)return;stackOper[topOper++] = oper;}/****************************************************************** 比较两个sour sour1 的优先级* 1 sour >= sour1 直接入操作符栈* 0 sour < sour1 直接入计算表达式栈*****************************************************************/ unsigned char comparPrior(char sour, char sour1){if(sour =='\0' ||sour1 == '\0') return 1;switch(sour){case '+':case '-':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-' ){return 0;}else{return 1;}break;case '*':case '/':if(sour1 == '*' ||sour1 == '/'||sour1 == '+' ||sour1 == '-'||sour1 == '('){return 1;}else{return 0;}break;default:return 1;break;}}/****************************************************************** 将输入的字符串转换为栈*****************************************************************/void StrToCal(char *pStr){int tmpNum = 0;char tmpOper;char islastNum = 0;//判断上一个字符是什么。
中缀表达式转后缀表达式以及后缀表达式的计算

else if(c=='(')
_push(&front,c);
else if(c==')')
{
data=_pop(&front);
}
while(data=_pop(&front))
{
postfix[k++]=(char)data;
}
postfix[k]='\0';
// printf("语法解析成功!\n");
return 1;
{
//如果操作符是*(乘法)
case '+':
return add(info,stack);break;
case '-':
return sub(info,stack);break;
for(i=0,k=0;i<len;++i)
{
c=input[i];
if(c>='a' &&c<='z' || c>='A' && c<='Z')
postfix[k++]=c;
else if(c>='0' && c<='9')
_push(&front,c);
}
else if(data=='+' || data=='-')
{
_push(&front,data);
中缀表达式转换成后缀表达式

实验三中缀表达式转换成后缀表达式,然后按后缀表达式计算实验一、实验目的:对所学数据结构知识进行温习,比如栈和队列的顺序存储结构和链式结构、大体操作进行温习;将一个中缀表达式转换成后缀表达式,然后按后缀表达式计算进行分析与设计,上机调试,最终达到应用的目。
二、实验要求:要求对中缀表达式转换成后缀表达式,然后按后缀表达式计算作设计性实验,并上机运行,撰写实验报告。
三、实验内容:将一个中缀表达式转换成后缀表达式,然后按后缀表达式计算,例如:5+(4+2)/2-3*2。
四、实验环境:Windows XP + VC++6.0开发环境。
五、上机调试代码:# include<stdio.h># include<stdlib.h>typedef char typedata1;typedef int typedata2;typedef struct charnode{typedata1 data;struct charnode *next;}charstack;typedef struct intnode{typedata2 data;struct intnode *next;}intstack;char s[100];charstack *creat(){ charstack *head;head=(charstack *)malloc(sizeof(charstack));head->data='#';head->next=0;return head;}intstack *intcreat(){ intstack *head;head=(intstack *)malloc(sizeof(intstack));head->data=0;head->next=0;return head;}charstack *push(charstack *top,char x){charstack *p;p=(charstack *)malloc(sizeof(charstack));p->data=x;p->next=top;top=p;return top;}intstack *intpush(intstack *top,int x){intstack *p;p=(intstack *)malloc(sizeof(intstack));p->data=x;p->next=top;top=p;return top;}typedata1 top(charstack *top){return top->data;}typedata2 inttop(intstack *top){return top->data;}char compare(char x1,char x2){char m;int m1,m2;if(x1=='+'||x1=='-') m1=0;else if(x1=='*'||x1=='/') m1=1;else if(x1=='(') m1=2;if(x2=='+'||x2=='-') m2=0;else if(x2=='*'||x2=='/') m2=1;else if(x2=='(') m2=2;if(m1>m2) m='>';else if(m1<m2) m='<';else m='=';return m;}charstack *popl(charstack *top){ charstack *p;if(top==0)printf("下溢!");else{p=top;top=top->next;free(p);return top;}}intstack *intpopl(intstack *top){ intstack *p;if(top==0)printf("下溢!");else{p=top;top=top->next;free(p);return top;}}void display(char m[],int n){int i;for(i=0;i<=n;i++)printf("%c",m[i]);}int change(char a[],int n){int i;int j=0;char x1,x2,bj;charstack *q;q=creat();for(i=0;i<n;i++){if(a[i]<='9'&&a[i]>='0'){s[j]=a[i];j=j+1;if(a[i+1]>'9'||a[i+1]<'0'){s[j]=' ';j=j+1;}}else{x1=a[i];x2=top(q);if(x2=='#')q=push(q,x1);else{if(x1==')'){while(top(q)!='('){s[j]=top(q);j=j+1;q=popl(q);}q=popl(q);}else{bijiao:bj=compare(x1,x2);switch(bj){case '>':q=push(q,x1);break;case '<':if(x2!='('){s[j]=top(q);j=j+1;q=popl(q);x2=top(q);if(x2!='#') goto bijiao; else q=push(q,x1);break;}else q=push(q,x1);break;case '=':s[j]=top(q);j=j+1;q=popl(q);q=push(q,x1);break;}}}}}while(top(q)!='#'){s[j]=top(q);j=j+1;q=popl(q);}return j;}int calculator(char s[],int n){int i,x1,x2,x;intstack *q;q=intcreat();for(i=0;i<=n;i++){if(s[i]==' ') i=i+1;if(s[i]<='9'&&s[i]>='0'){x1=(int)s[i]-48; while(s[i+1]<='9'&&s[i+1]>='0'){x1=10*x1+(int)s[i+1]-48;i=i+1;}q=intpush(q,x1); }else if(s[i]=='+'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1+x2); }else if(s[i]=='-'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1-x2); }else if(s[i]=='*'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1*x2); }else if(s[i]=='/'){ x2=inttop(q);q=intpopl(q);x1=inttop(q);q=intpopl(q);q=intpush(q,x1/x2);}}x=inttop(q);return x;}void main(){int i,k;char f[100];printf("请输入中缀表达式(输入#终止):\n");for(i=0;i<100;i++){scanf("%c",&f[i]);if(f[i]=='#')break;}printf("\n后缀表达式为:");k=change(f,i);display(s,k);printf("\n\n计算结果为:%d\n\n",calculator(s,k)); }六、实验结果分析:1)实验运行结果及测试截图如下:2)本实验对字符也一样能得出后缀表达式,可是没有赋具体值,故不能算结果,同时呢也会弹出运用程序错误提示,测试截图如下:3)实验改良,若是本实验能在改良为,当输入为字符时自动提示为此字符赋值,那么此程序也将能计算出带有字符的的表达式的结果,同时本实验也能够通过其它算法实现。
【Java数据结构】中缀表达式转后缀表达式,后缀表达式的计算(多位数)

【Java数据结构】中缀表达式转后缀表达式,后缀表达式的计算(多位数)中缀表达式转后缀表达式,后缀表达式的计算(多位数)中缀表达式转后缀表达式思路(1)初始化两个栈stack1与stack2,分别存储数和操作符(2)从左到右扫描中缀表达式(3)遇到数字时,直接将其压⼊stack1中(4)遇到操作符时,先进性⽐较优先级,如果优先级⽐栈顶元素的⾼,则直接⼊栈如果优先级⽐栈顶元素的低,则将栈顶元素弹出压⼊数栈,再将操作符与栈顶重复⽐较,直到可以⼊栈如果符号栈为空或者栈顶是左括号(,则直接⼊栈如果操作符是右括号),则将操作符依次出栈放⼊数栈中,直到遇到左括号,⼆者直接丢弃(5)扫描完成,将操作符栈stack2依次出栈并压⼊stack1中后缀表达式计算器思路(1)初始化⼀个栈(2)遇到数字时,直接将数字压⼊栈(3)遇到运算符时,将栈顶的两个数弹出,并且计算,将结果⼊栈Java代码如下1import java.util.ArrayList;2import java.util.Deque;3import java.util.LinkedList;4import java.util.List;56public class Main {7public static void main(String[] args) {8 String str ="11+(2*4)+3*(61-1)";//结果为11+8+180=1999//将字符串转成list10 List<String> List = toInfixExpressionList(str);11 System.out.println(List);12//中缀表达式转后缀表达式13 List<String> suffixList = prefixToSuffix(List);14 System.out.println(suffixList);15//计算后缀表达式的结果16 System.out.println("后缀表达式的计算结果为:"+toCalculation(suffixList));17 }1819/**20 * 将表达式每⼀个部分转换成list21 * @param str 计算表达式22 * @return List23*/24public static List<String> toInfixExpressionList(String str){25 List<String> list = new ArrayList<>(str.length());26int i = 0;//⽤于遍历表达式的指针27char c;//⽤于存储每⼀个遍历到的字符28 StringBuilder s;//⽤于多位数的拼接29while (i<str.length()){30 c = str.charAt(i);31//如果是⾮数字,直接加⼊到list32if(c < 48 || c > 57){33 list.add(""+c);34 i++;35 }else {36 s = new StringBuilder();37while (c >= 48 && c <= 57){38 s.append(c);39 i++;40 c = str.charAt(i);41 }42 list.add(s.toString());43 }44 }45return list;46 }4748/**49 * 计算后缀表达式50 * @return计算结果51*/52public static Integer toCalculation(List<String> list){53 Deque<String> stack = new LinkedList<>();54for(String item: list){55if(isNumeric(item)){56 stack.push(item);57 }else {58int x = Integer.parseInt(stack.pop());59int y = Integer.parseInt(stack.pop());60switch (item){61case "+":62 stack.push((y+x)+"");63break;64case "-":65 stack.push((y-x)+"");66break;67case "*":68 stack.push((y*x)+"");69break;70case "/":71 stack.push((y/x)+"");72break;73default:74throw new RuntimeException("输⼊错误!");75 }76 }77 }78return Integer.parseInt(stack.pop());79 }8081/**82 * 中缀表达式转后缀表达式83 * @return List84*/85public static List<String> prefixToSuffix(List<String> list){86//初始化两个栈,stack1为数栈,stack2为操作符栈87 List<String> stack1 = new ArrayList<>();88 Deque<String> stack2 = new LinkedList<>();89for(String item: list){90if(isNumeric(item)){91//数字直接⼊栈92 stack1.add(item);93 }else if(item.equals("(")) {94//左括号或者空直接⼊栈95 stack2.push(item);96 }else if(item.equals(")")){97//右括号将符号栈中左括号前的所有符号⼊数栈98while (!stack2.peek().equals("(")){99 stack1.add(stack2.pop());100 }101 stack2.pop();//清除括号102 }else if(stack2.peek()==null||judgePriority(item)>judgePriority(stack2.peek())){ 103//优先级⽐栈顶元素⾼,直接⼊栈104 stack2.push(item);105 }else {106//优先级⽐栈顶元素低或者相等,将栈顶优先级⾼的⼊数栈107while (stack2.peek()!=null&&judgePriority(stack2.peek())<=judgePriority(item)){ 108 stack1.add(stack2.pop());109 }110 stack2.push(item);111 }112 }113while (stack2.peek()!=null){114 stack1.add(stack2.pop());115 }116117return stack1;118 }119120/**121 * 返回运算符优先级,加减为1,乘除为2122 * @param str 运算符123 * @return优先级124*/125public static int judgePriority(String str){126switch (str){127case "+":128return 1;129case "-":130return 1;131case "*":132return 2;133case "/":134return 2;135case "(":136return 0;137case ")":138return 0;139default:140throw new RuntimeException("输⼊有误!"+str); 141 }142 }143144/**145 * 判断字符串是否是正整数146 * @param str 字符串147 * @return boolean148*/149public static boolean isNumeric(String str){150for (int i = str.length();--i>=0;){151if (!Character.isDigit(str.charAt(i))){152return false;153 }154 }155return true;156 }157 }。
后缀表达式转换和计算

后缀表达式转换和计算将一个表达式转换成后缀表达式,并利用后缀表达式进行计算时,需要使用两个栈。
将一个中缀表达式转换成后缀表达式,需要用运算符栈进行;利用后缀表达式进行计算,则需要一个操作数栈。
转换时,首先定义各个运算符的优先级,才能根据规则实现转换。
具体程序如下:#include <malloc.h>#include <stdio.h>#include <ctype.h>#include <string.h>#define maxsize 100typedef struct sqstack{ /*运算符栈*/char stack[maxsize];int top;}sqstack;typedef struct sqstack2{ /*操作数栈*/int stack[maxsize];int top;}sqstack2;void Convert(char *exp,char *result);char op[6]={'+','-','*','/','(','#'}; /*运算符字符*/int pre[6]={1,1,2,2,0,-1}; /*运算符优先级*/void Initstack(sqstack *s){ /*运算符栈初始化*/s->top=0;}void Push(sqstack *s,char x){ /*运算符栈入栈*/if (s->top==maxsize-1) printf("Overflow1\n");else{s->stack[s->top]=x;s->top++;}}void Pop(sqstack *s,char *x){ /*运算符栈出栈*/if (s->top==0) printf("underflow1\n");else{s->top--;*x=s->stack[s->top];}}char Gettop(sqstack s){ /*运算符栈取栈顶元素*/ if (s.top==0){printf("underflow3\n");return 0;}else return s.stack[s.top-1];}void Initstack2(sqstack2 *s){ /*操作数栈初始化*/ s->top=0;}void Push2(sqstack2 *s,int x){ /*操作数栈入栈*/ if (s->top==maxsize-1) printf("Overflow2\n");else{s->stack[s->top]=x;s->top++;}}void Pop2(sqstack2 *s,int *x){ /*操作数栈出栈*/ if (s->top==0) printf("underflow2\n");else{s->top--;*x=s->stack[s->top];}}char f(char c){ /*定位运算符在对应数组的下标*/ switch (c) {case '+': return 0;case '-': return 1;case '*': return 2;case '/': return 3;case '(': return 4;case ')': return 5;default: return 6;}}int precede(char c1,char c2){ /*计算运算符优先级的大小*/int i1=f(c1);int i2=f(c2); /*找到字符在f数组中的位置,以方便确定其优先等级*/return pre[i1]-pre[i2];}int Operate(int a,char theta,int b){ /*对制定的操作数进行theta运算*/int sum;switch (theta) {case '+': sum=a+b; break;case '-': sum=a-b; break;case '*': sum=a*b; break;case '/': sum=a/b;}return sum;}void Convert(char *exp,char *result){ /*将中缀表达式串转换成后缀表达式串,用空格间隔各项*/sqstack OPTR;char c,x;int i=0;Initstack(&OPTR);Push(&OPTR,'#');while(*exp!='\0'){c=*exp++;if(isdigit(c)) { /*若为操作数,直接送后缀表达式*/while(isdigit(c)) {result[i++]=c;c=*exp++;}result[i++]=' ';exp--;continue;}if(c==')'){ /*若为')',出栈直至'('*/Pop(&OPTR,&x);while(x!='('){result[i++]=x;result[i++]=' ';Pop(&OPTR,&x);}continue;}if(c=='#'){ /*若为'#',出栈直至'#'*/Pop(&OPTR,&x);while(x!='#'){result[i++]=x;result[i++]=' ';Pop(&OPTR,&x);}break; /*表达式串处理结束*/}if(c=='(') { /*若为'(',直接入栈*/Push(&OPTR,c);continue;}else{ /*否则为运算符,与栈顶运算符比较*/if(precede(c,Gettop(OPTR))>0) Push(&OPTR,c); /*若优先级大于栈顶运算符,直接入栈*/else{ /*否则,优先级小于等于栈顶运算符*/Pop(&OPTR,&x); /*栈顶运算符出栈*/result[i++]=x;result[i++]=' ';while(precede(c,Gettop(OPTR))<=0){Pop(&OPTR,&x); /*栈顶运算符出栈*/result[i++]=x;result[i++]=' ';}Push(&OPTR,c);}continue;}}result[i++]='\0';}int Evalution(char *npl){sqstack2 OPND;int a,b,sum,result;char c;Initstack2(&OPND);while(*npl){c=*npl++;if(isdigit(c)){sum=0;while (isdigit(c)) {sum=sum*10+(c-'0');c=*npl++;}Push2(&OPND,sum);/*把数字串转化成十进制数字再压栈*/}else{Pop2(&OPND,&b);Pop2(&OPND,&a);Push2(&OPND,Operate(a,c,b));npl++;}}Pop2(&OPND,&result);return result;}int main(){char result[80],exp[80];printf("输入你的算术表达式,参与运算的都是正整数,不需输入等号,以#结束输入:\n");gets(exp); /*输入中缀表达式串*/Convert(exp,result); /*转换成后缀表达式串*/puts(result); /*输出后缀表达式串*/printf("The result is %d",Evalution(result)); /*利用后缀表达式计算并输出结果*/return 0;}。
c 实现中缀表达式转后缀表达式比计算值

c 实现中缀表达式转后缀表达式比计算值C语言是一种广泛应用的编程语言,它具有高效、可移植、灵活等特点,在计算机科学领域有着广泛的应用。
中缀表达式是我们常见的数学表达方式,而将中缀表达式转换为后缀表达式是一项常见的任务。
本文将介绍如何使用C语言实现中缀表达式转后缀表达式,并计算其值。
我们需要了解中缀表达式和后缀表达式的概念。
中缀表达式是我们常见的数学表达方式,其中操作符位于操作数之间,如"3 + 4"。
而后缀表达式(也称为逆波兰表达式)是一种更加简洁的数学表达方式,其中操作符位于操作数之后,如"3 4 +"。
后缀表达式的计算更加简单直观,因此在计算机中更为常见。
接下来,我们需要实现一个函数来将中缀表达式转换为后缀表达式。
我们可以使用栈这一数据结构来辅助实现。
具体的步骤如下:1. 创建一个栈,用于存储操作符。
2. 遍历中缀表达式的每个字符。
3. 如果当前字符是操作数,直接输出。
4. 如果当前字符是操作符,并且栈为空,将操作符入栈。
5. 如果当前字符是操作符,并且栈不为空,比较当前操作符与栈顶操作符的优先级。
- 如果当前操作符的优先级大于栈顶操作符的优先级,将当前操作符入栈。
- 如果当前操作符的优先级小于等于栈顶操作符的优先级,将栈顶操作符出栈并输出,直到栈为空或者栈顶操作符的优先级小于当前操作符。
- 将当前操作符入栈。
6. 如果当前字符是左括号"(",将其入栈。
7. 如果当前字符是右括号")",将栈顶操作符出栈并输出,直到栈顶操作符为左括号"("。
8. 遍历结束后,将栈中剩余的操作符依次出栈并输出。
通过上述步骤,我们可以将中缀表达式转换为后缀表达式。
接下来,我们需要计算后缀表达式的值。
为了计算后缀表达式的值,我们可以使用另一个栈来辅助实现。
具体的步骤如下:1. 创建一个栈,用于存储操作数。
2. 遍历后缀表达式的每个字符。
数据结构中缀式中缀表达式改后缀表达式并求值

《数据结构》课程设计报告课程设计题目:中缀表达式改后缀表达式并求值一. 实验目的·掌握栈的特征及基本操作,如入栈、出栈等,栈的顺序存储结构和链式存储结构的实现,以便在实际问题中灵活应用。
·掌握栈的典型应用——中缀表达式转后缀表达式,并利用后缀表达式求值。
二. 实验内容(一)中缀表达式转后缀表达式的方法:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将栈中的元素依次出栈,输出。
(二)三. 实验分析程序源码(要求对每个函数及主要代码加上注释语句),源码出处。
//// main.c// 后缀表达式求值//// Created by 颜彦闻on 14/12/2.// Copyright (c) 2014年颜彦闻. All rights reserved.//#include <stdio.h>#include <stdlib.h>#define StackSize 100#define QueueSize 100typedef char DataType;typedef struct{char data[100];int front,rear;}SeqQueue; //定义队列类型void InitQueue(SeqQueue *Q) //初始化队列{Q->front=0;Q->rear=0;}int QueueEmpty(SeqQueue Q) //判空{return Q.rear==Q.front;}void EnQueue(SeqQueue *Q,DataType x) //元素入队列函数{if((Q->rear+1)%QueueSize==Q->front)printf("Queue overflow");else{Q->data[Q->rear]=x;Q->rear=(Q->rear+1)%QueueSize;}}DataType DeQueue(SeqQueue *Q){char x;if(QueueEmpty(*Q))return0;else{x=Q->data[Q->front];Q->front=(Q->front+1)%QueueSize;return x;}}//栈的相关操作typedef struct{DataType data[100];int top;}SeqStack;void InitStack(SeqStack *S) //栈的初始化{S->top=-1;}void Push(SeqStack *S,DataType x) //进栈函数{if(S->top==StackSize-1)printf("stack overflow");else{S->top=S->top+1;S->data[S->top]=x;}}DataType Pop(SeqStack *S) //退栈顶指针函数{if(S->top==-1){printf("stack underflow");return0;}elsereturn S->data[S->top--];}DataType GetTop(SeqStack S) //取栈顶元素{if(S.top==-1){printf("stack empty");return0;}elsereturn S.data[S.top];}int Priority(DataType op) //求运算符优先级函数{switch(op){case'(':case'#':return0;case'-':case'+':return1;case'*':case'/':return2;}return -1;}void CTPostExp(SeqQueue *Q){SeqStack S;char c,t;InitStack(& S);Push(&S,'#');do{c=getchar();switch(c){case' ':break;case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':EnQueue(Q ,c);break;case'(':Push(&S,c);break;case')':case'#':{do{t=Pop(&S);if(t!='('&&t!='#')EnQueue(Q ,t);}while(t!='('&&S.top!=-1);break;}case'+':case'-':case'*':case'/':while(Priority(c)<=Priority(GetTop(S))){t=Pop(&S);EnQueue(Q,t);}Push(&S,c);break;}}while(c!='#');}DataType CPostExp(SeqQueue Q){SeqStack S;char ch;int x,y;InitStack(&S);while(!QueueEmpty(Q)){ch=DeQueue(&Q);if(ch>='0'&&ch<='9')Push(&S,ch);else{y=Pop(&S)-'0';x=Pop(&S)-'0';switch(ch){case'+': Push(&S,(char)(x+y+'0'));break;case'-': Push(&S,(char)(x-y+'0'));break;case'*': Push(&S,(char)(x*y+'0'));break;case'/': Push(&S,(char)(x/y+'0'));break;}}}return GetTop(S);}int main(int argc, char *argv[]){SeqQueue Q;InitQueue(&Q);printf("输入表达式:\n");CTPostExp(&Q);printf("结果:%c\n",CPostExp(Q));printf("后缀表达式:");while(!QueueEmpty(Q))printf("%2c",DeQueue(&Q));printf("\n");system("PAUSE");return0;}四. 算法时间复杂度。
中缀表达式转化成后缀表达式的计算

目录一、设计思想 (01)二、算法流程图 (02)三、源代码 (03)四、运行结果 (16)五、遇到的问题及解决 (17)六、心得体会 (18)一、设计思想第一种算法先把算术表达式转化成后缀表达式,在对后缀表达式进行计算。
首先建立一个符号栈,用于存放字符和字符的优先级别;然后在建立一个数栈,用于辅助后缀表达式的计算;最后在定义一个字符串数组,用于存放后缀表达式。
建立一个计算的函数,该函数用于两个数的计算,在调用这个函数的时候,传入三个参数,两个浮点型参数和一个字符型参数,根据不同的符号进行不同的计算。
定义一个判断优先级别的函数,用于判断两个操作符的优先级别,在根据优先级的不同决定不同的操作。
后缀表达式的取得,对算术表达式字符串进行挨个的扫描,如果是数字或者是小数点,则将数字或者小数点存放到字符数组中,每取完一个数字,则在后面用“|”隔开,如果是操作符,则和栈中得操作符进行比较,若扫描到的符号优先级比栈里的符号优先级低,则栈中元素出栈并存放到字符数组中。
每出一个字符到字符数组中就在后面加“|”分隔。
继续检查栈顶比较优先级,直到栈中元素优先级比扫描到的符号优先级低或者符号栈为空,则将此操作符入栈。
若是“(”则无条件入字符栈,若是“)”则从字符栈中出字符直到遇到“(”为止。
当字符数组扫描到最后的时候,计算并没有结束。
然后得进行字符栈的判断,看是否已经为空栈,若不是空栈,则出栈字符,将字符存放到数组中。
最后字符串数组中存放的就是后缀表达式。
得到后缀表达式后,要用数栈进行后缀表达式的计算,后缀表达式的计算中,对新的数组进行从道到尾的扫描,如果遇到数字,以“|”为标记取出完整的操作数,用辅助数组存放,然后转化成浮点数存放到数栈中,遇到“|”则直接将数组下标往后走。
遇到字符,则从数栈取出两个数进行计算,将计算的结果从新存放到数栈中,循环直到接到结束。
最后存放在数栈中的数就是计算的结果。
最后在主函数中调用此函数,进行结果的输出。
用栈和二叉树实现中缀表达式转后缀表达式构建计算机并求值实验报告

实验报告姓名:黄雄镖学号:13331093院系专业:软件学院2013级教务4班完成日期:2014 年10 月20 日实验题目:实现一个较为通用的计算器需求分析:实现一个包含加减乘除运算的较为通用的计算器,操作数可能是负数,并且可能是多位数。
运算式中可以有括号和多余空格。
计算器对负号不敏感, 形如1+-1或者1+(-1)都是可以接受的。
概要设计思路: 将表达式的中缀表达式转换成后缀表达式,然后利用一个栈或者建立二叉树对后缀表达式进行求值。
由于多位数在转为后缀表达式时会分不清, 故在每个数和运算符后面加上一个空格作为区别在主程序中调用用栈求值的计算器类和用二叉树计算的计算器类, 输出算式的结果13331093_03.h里存放用栈求值的计算器类13331093_03_tree.h里存放用二叉树计算的计算器类13331093_03.h的类里主要包括:获得算术表达式的函数getexpression(string expression), expression为所要计算的算术表达式计算函数calculate(string num2, string num1, string op), 输入为两个数(字符串形式)和一个操作符, 返回值为计算结果(字符串形式)返回中缀表达式函数ShowMiddleExpression(), 返回的中缀表达式为字符串形式RidSpace(string origin)用于去除输入中多余的空格, 输入为要除去空格的算术表达式, 返回去掉空格的算术表达式MidToLast(string str)中缀表达式转后缀表达式获得后缀表达式函数GetLastExpression(), 返回的后缀表达式为字符串形式用栈执行计算后缀表达式函数exe(), 返回计算结果为字符串形式13331093_03_tree.h类里主要包括:获得算术表达式的函数getexpression(string expression), expression为所要计算的算术表达式计算函数calculate(string num2, string num1, string op), 输入为两个数(字符串形式)和一个操作符, 返回值为计算结果(字符串形式)返回中缀表达式函数ShowMiddleExpression(), 返回的中缀表达式为字符串形式RidSpace(string origin)用于去除输入中多余的空格, 输入为要除去空格的算术表达式, 返回去掉空格的算术表达式MidToLast(string str)中缀表达式转后缀表达式获得后缀表达式函数GetLastExpression(), 返回的后缀表达式为字符串形式生成一颗二叉树的函数makeTree(TNode *&p)后序遍历二叉树并计算的函数PostOrder(TNode *p), 返回计算结果为字符串形式a.调试过程遇到的问题与解决方案:遇到的问题:调试过程中出现程序崩溃的现象, 后来debug发现是没有考虑到执行运算过程中出现的-()的情况原因:没有考虑-()的情况, 导致栈为空的时候还弹出元素解决方案:特殊处理这种情况b.时间和空间复杂度:除去输入中空格的操作的时间复杂度为O(n),中缀表达式转后缀表达式的时间复杂度为O(n), 用栈执行运算的时间复杂度为O(n),后序遍历二叉树的时间复杂度为O(n) 所以用栈计算或者用二叉树计算的操作的时间复杂度为都是O(n)栈属于线性表, 故用栈计算的空间复杂度为O(n)用二叉树计算的空间复杂度也是O(n)主程序:输入一个整数m,代表有m个输入接下来有m行,每一行输入你要计算的式子13331093_03.h:含有用stack计算的计算器类用法:calculator c_stack 声明一个计算器对象c_stack.getexpression(expression) 把算术表达式存入计算器中expression为所要计算的算术表达式c_stack.GetLastExpression() 获取算术表达式的后缀表达式c_stack.exe() 获取计算结果13331093_03_tree.h:含有用二叉树计算的计算器类用法:calculator_tree c_tree 声明一个计算器对象c_tree.getexpression(expression) 把算术表达式存入计算器中expression为所要计算的算术表达式c_tree.GetLastExpression() 获取算术表达式的后缀表达式c_tree.makeTree(tree) 建立一棵二叉树c_tree.PostOrder(tree) 后序遍历二叉树并返回计算结果测试结果在主程序中调用用栈求值的计算器类和用二叉树计算的计算器类, 并对输入表达式进行两种方法所生成的后缀表达式和结果的对比测试代码在test.cpp中测试输入:11-(12.34)-11+-21+(-2)11 + 23 * 32/4-8-1.234/5 *(1 +3)2.333*4-(3+(-5))12345+5432.1/(-12345)-(100 ) * 0.5 -(-22.22)1234/-123+3.333-( 123*50 ) / 2.2测试结果如下:另外我用计算器算过, 结果是正确的实验心得通过这次实验, 我对栈和二叉树的理解加深了很多。
编译原理 中缀表达式转换成后缀表达式,并按后缀表达式计算

实验三中缀表达式转换成后缀表达式,并按后缀表达式计算[实验目的]对中缀表达式转换成后缀表达式,然后按后缀表达式计算进行分析与设计,并上机运行。
使学生能通该实验理解对一个简单表达式的编译实现过程。
[实验要求]要求对中缀表达式转换成后缀表达式,然后按后缀表达式计算作设计性实验,并上机运行,写出实验报告。
[实验时数]2学时。
[实验内容]中缀表达式转换成后缀表达式,然后按后缀表达式计算,例如:A*(B+C)/D-E*(F+G)。
[实验环境]硬件坏境:实验室209、一人一台机子。
软件坏境:Windows XP、Visual studio 6.0[算法描述及实验步骤]根据本实验内容的要求,实验要实现的是一个中缀表达式转换成后缀表达式并输出。
通过设计一个算法来实现以上实验。
[调试过程]运行Visual studio 6.0。
打开事先编写的程序:中缀到后缀.cpp。
在Visual studio 6.0环境下进编译、调试、运行。
多次重复无错误后,输出结果。
[实验结果][实验总结][附录]#include<stack>#include<iostream>using namespace std;bool prior(char op1,char op2) {bool ret=false;switch (op1){case'+':case'-':switch(op2){case'+':case'-':case'*':case'/':ret= false;break;case'#':case'(':ret = true;break;}break;case'*':case'/':switch(op2){case'#':case'+':case'-':case'(':ret= true;break;case'*':case'/':ret= false;break;}break;}return ret;}int main(int argc, char* argv[]){char s[]="A*(B+C)/D-E*(F+G)";int k;for(k=0;k<17;k++){cout<<s[k];}cout<<endl;stack<char> operS;//操¨´作Á¡Â符¤?栈?int i=0;operS.push('#');while(s[i]!='\0'){if(s[i]==' '){i++;continue;}if(s[i]>='A' && s[i]<'Z' ) //是º?字Á?母?{cout<<s[i];}else//不?是º?字Á?母?{switch(s[i]){case'+':case'-':case'*':case'/':if(prior(s[i],operS.top()))//比À¨¨栈?顶£¤优®?先¨¨级?高?,直¡À接¨®进?栈?{operS.push(s[i]);}else if(operS.top()!='(') //比À¨¨栈?顶£¤优®?先¨¨级?低̨ª,ê?先¨¨出?栈?,s[i]进?栈?{cout<<operS.top();operS.pop();operS.push(s[i]);}break;case'(': //直¡À接¨®进?栈?operS.push(s[i]);break;case')': //匹£¤配?栈?内¨²的Ì?'(',都?出?栈?,ê?并¡é删¦?除y'(' while(operS.top()!='('){cout<<operS.top();operS.pop();}operS.pop();break;case'#':break;}}i++;}while(!operS.empty()){cout<<operS.top();operS.pop();}cout<<endl;int a;cin >> a;return 0;}[教师评语]。
将中缀表达式转换为后缀表达式并计算

《数据结构》实验报告◎实验题目:使用键盘输入表达式,计算表达式的值并输出;将表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。
◎实验目的:使用栈的操作编写关于数据结构的程序。
◎实验内容:写出程序并上机调试、通过。
一、需求分析1、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“请输入表达式”时输入中缀表达式。
然后计算机终端输出转换后的后缀表达式及计算后的结果。
2、程序执行的命令包括:(1)构造链栈;(2)输入数据;(3)判断输入的表达式是否为非法表达式;(4)将中缀表达式转换为后缀表达式;(5)计算表达式的值;(6)输出。
(7)结束4、本程序能将中缀表达式转换为后缀表达式,并且能计算表达式的值。
5、输入及输出示例:例1:请输入表达式6+3*(6+5)后缀表达式:6 3 6 5 + * +计算结果为:39Press any key to continue例2:请输入表达式6-3*(7+1ERROR:表达式错误Press any key to continue二概要设计1.基本操作(1)、struct node操作结果:创建结构体(2)、int Searchexpression(char string1[])初始条件:表达式string1已经存在。
操作结果:判断表达式是否非法(3)、struct node *Initialization()操作结果:创建栈链。
(4)、struct node *assort(struct node *s)初始条件:string1、string2已存在。
操作结果:将中缀表达式转换为后缀表达式并存在string2中。
(5)、struct node *calcolate(struct node *s)操作结果:求出表达式的值2、模块调用图三详细设计1、每个模块:(1) 定义结构体struct node{char data;int num;struct node *next;};(2) 判断表达式是否非法int Searchexpression(char string1[]){int i1,b1,b2;int m;m=strlen(string1);if(string1[0]<'0'||string1[0]>'9'){printf("ERROR:表达式缺操作数!\n");return(WRONG);}for(i1=0;i1<=m;i1++){if(string1[i1]=='(')b1++;elseif(string1[i1]==')')b2++;}if(b1!=b2){printf("ERROR:缺少括号\n");return(WRONG);}for(i1=0;i1<m;i1++)if('0'<=string1[i1]&&string1[i1]<='9'&&'0'<=string1[i1+1]&&str ing1[i1+1]<='9'){ printf("ERROR:表达式缺操作符!\n");return(WRONG);}for(i1=0;i1<=m;i1++)if(string1[i1]=='+'&&(string1[i1+1]=='+'||string1[i1+1]=='-'||stri ng1[i1+1]=='*'||string1[i1+1]=='/')){ printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='-'&&(string1[i1+1]=='+'||string1[i1+1]=='-'||strin g1[i1+1]=='*'||string1[i1+1]=='/')){ printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='*'&&(string1[i1+1]=='+'||string1[i1+1]=='-'||strin g1[i1+1]=='*'||string1[i1+1]=='/')){printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='/'&&(string1[i1+1]=='+'||string1[i1+1]=='-'||string1[i1+1]=='*'||string1[i1+1]=='/')){printf("ERROR:表达式缺操作数!\n");return(WRONG);}return(RIGHT);}(3)、将中缀表达式转换为后缀表达式struct node *assort(struct node *s)//输入字符串{struct node *p,*top;int i;top=s;int m;char a;m=strlen(string1);for(i=0;i<=m;i++){a=string1[i];if('0'<=string1[i]&&string1[i]<='9'){string2[j]=string1[i];j++;}else{switch(a){case '(':{p=(struct node *)malloc(sizeof(struct node));p->data=a;p->next=top;top=p;break;}case '*':case '/':string2[j]=' ';j++;if((top->data=='*')||(top->data=='/')){string2[j]=top->data;j++; //比其高,现将栈顶运算符出栈,再进栈。
中缀表达式转后缀表达式并计算结果

中缀表达式转后缀表达式并计算结果⽬录1 栈的概念容器,先进后出规则;如图为表达式:a+(b*c) 逐个操作符、操作数⼊栈过程;出栈为该过程逆序2 何谓中缀表达式型如:a - b + c 的普通算术表达式,我们称之为中缀表达式。
3 后缀表达式(逆波兰)3.1 概念以及案例中缀表达式:a - b + c ,转化为后缀表达式:ab-c+;后缀表达式运算规则:1. 遇到操作数直接⼊栈,遇到操作符,从栈顶弹出两个操作数,并计算如下表达式结果压栈,直⾄最终弹出栈中最后⼀个数即停⽌算法,该记法的表达式称为后缀表达式后出栈操作数(两数中更靠近栈底者) (操作符[+_*/])先出栈操作数(栈顶)2. ab-c+计算过程如下图:3.2 求解⽅法⼊栈优先级{ [ ( > 乘= 除> 加= 减3.2.1 流程图弹出案例:扫描位优先级较⼩,扫描位为 " - "。
左括号虽然优先级⼤,但是左括号只在碰到,匹配的右括号时弹出3.2.2 推导相等优先级为何弹出栈顶只关注相同有优先级下是否弹出栈顶先加,后加减中缀表达式后缀表达式a +b +c abc++ 或 ab+c+a +b -c ab+c- 或 abc-+中缀表达式后缀表达式此例中,当需要判断操作符间优先级:栈顶为:+(加),栈外判断位:+ 或 - 。
此时若优先级相等,既可弹出栈顶操作符,也可不弹直接当前位压栈。
先减,后加减中缀表达式后缀表达式a -b +c ab-c+a -b -c ab-c-此例中,当需要判断操作符间优先级:栈顶为:-(减),栈外判断位:+ 或 - 。
此时若优先级相等,则只能弹出当前栈顶操作符。
先乘,后乘除中缀表达式后缀表达式a *b *c abc** 或 ab ca *b /c ab c/ 或 abc/此例中,当需要判断操作符间优先级:栈顶为:(乘),栈外判断位:或 / 。
此时若优先级相等,既可弹出栈顶操作符,也可不弹直接当前位压栈。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》实验报告◎实验题目:使用键盘输入表达式,计算表达式的值并输出;将表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。
◎实验目的:使用栈的操作编写关于数据结构的程序。
◎实验内容:写出程序并上机调试、通过。
一、需求分析1、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“请输入表达式”时输入中缀表达式。
然后计算机终端输出转换后的后缀表达式及计算后的结果。
2、程序执行的命令包括:(1)构造链栈;(2)输入数据;(3)判断输入的表达式是否为非法表达式;(4)将中缀表达式转换为后缀表达式;(5)计算表达式的值;(6)输出。
(7)结束4、本程序能将中缀表达式转换为后缀表达式,并且能计算表达式的值。
5、输入及输出示例:例1:请输入表达式6+3*(6+5)后缀表达式:6 3 6 5 + * +计算结果为:39Press any key to continue例2:请输入表达式6-3*(7+1ERROR:表达式错误Press any key to continue二概要设计1.基本操作(1)、struct node操作结果:创建结构体(2)、int Searchexpression(char string1[])初始条件:表达式string1已经存在。
操作结果:判断表达式是否非法(3)、struct node *Initialization()操作结果:创建栈链。
(4)、struct node *assort(struct node *s)初始条件:string1、string2已存在。
操作结果:将中缀表达式转换为后缀表达式并存在string2中。
(5)、struct node *calcolate(struct node *s)操作结果:求出表达式的值2、模块调用图三详细设计1、每个模块:(1) 定义结构体struct node{char data;int num;struct node *next;};(2) 判断表达式是否非法int Searchexpression(char string1[]){int i1,b1,b2;int m;m=strlen(string1);if(string1[0]<'0'||string1[0]>'9'){printf("ERROR:表达式缺操作数!\n");return(WRONG);}for(i1=0;i1<=m;i1++){if(string1[i1]=='(')b1++;elseif(string1[i1]==')')b2++;}if(b1!=b2){printf("ERROR:缺少括号\n");return(WRONG);}for(i1=0;i1<m;i1++)if('0'<=string1[i1]&&string1[i1]<='9'&&'0'<=string1[i1+1]&&str ing1[i1+1]<='9'){ printf("ERROR:表达式缺操作符!\n");return(WRONG);}for(i1=0;i1<=m;i1++)if(string1[i1]=='+'&&(string1[i1+1]=='+'||string1[i1+1]=='-'|| string1[i1+1]=='*'||string1[i1+1]=='/')){ printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='-'&&(string1[i1+1]=='+'||string1[i1+1]=='-'|| string1[i1+1]=='*'||string1[i1+1]=='/')){ printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='*'&&(string1[i1+1]=='+'||string1[i1+1]=='-'|| string1[i1+1]=='*'||string1[i1+1]=='/')){printf("ERROR:表达式缺操作数!\n");return(WRONG);}elseif(string1[i1]=='/'&&(string1[i1+1]=='+'||string1[i1+1]=='-'|| string1[i1+1]=='*'||string1[i1+1]=='/')){printf("ERROR:表达式缺操作数!\n");return(WRONG);}return(RIGHT);}(3)、将中缀表达式转换为后缀表达式struct node *assort(struct node *s)//输入字符串{struct node *p,*top;int i;top=s;int m;char a;m=strlen(string1);for(i=0;i<=m;i++){a=string1[i];if('0'<=string1[i]&&string1[i]<='9'){string2[j]=string1[i];j++;}else{switch(a){case '(':{p=(struct node *)malloc(sizeof(struct node));p->data=a;p->next=top;top=p;break;}case '*':case '/':string2[j]=' ';j++;if((top->data=='*')||(top->data=='/')){string2[j]=top->data;j++; //比其高,现将栈顶运算符出栈,再进栈。
top->data=a;break;}else{p=(struct node *)malloc(sizeof(struct node));//否,直接进栈p->data=a;p->next=top;top=p;break;}case '+':case '-':{string2[j]=' ';j++;if(top->data=='+'||top->data=='-'||top->data=='*'||top->data== '/'){string2[j]=top->data;j++;top->data=a;break;}else{p=(struct node *)malloc(sizeof(struct node));p->data=a;p->next=top;top=p;break;}}case ')':{string2[j]=' ';j++;if(top->data=='@'){printf("input error");break;}while(top->data!='('){string2[j]=top->data;j++;p=top;top=top->next;free(p);}p=top;top=top->next;free(p);break;}}}}while(top->data!='@'){string2[j]=top->data;j++;p=top;top=top->next;free(p);}string2[j]='#';printf("后缀表达式为:");for(i=0;i<j;i++)if(string2[i]!=' ')printf("%c ",string2[i]);printf("\n ");return top;}(4)表达式求值struct node *calcolate(struct node *s){struct node *top,*p;char *q;int x,y,a;int i,n;top=s;//指向栈顶的指针for(i=0;i<=j;i++)//遍历字符串string2{if(string2[i]>='0'&&string2[i]<='9'){q=&string2[i];a=atoi(q);for(n=i;string2[n]>='0'&&string2[n]<='9';n++){} p=(struct node *)malloc(sizeof(struct node ));p->num=a;p->next=top;top=p;i=n-1;}elseif(string2[i]=='#') //遇#号结束标志,输出栈中的最后计算结果printf("计算结果为:%d\n",top->num);else{if(string2[i]==' '){}else{y=top->num;p=top;top=top->next;free(p);x=top->num;p=top;top=top->next;free(p);switch(string2[i]){case '+':{a=x+y;p=(struct node *)malloc(sizeof(struct node));p->num=a;p->next=top;top=p;break;}case '-':{a=x-y;p=(struct node *)malloc(sizeof(struct node ));p->num=a;p->next=top;top=p;break;}case '*':{a=x*y;p=(struct node *)malloc(sizeof(struct node ));p->num=a;p->next=top;top=p;break;}case '/':{if(y==0)printf("ERROR:除数为零!\n");a=(float)x/y;p=(struct node *)malloc(sizeof(struct node ));p->num=a;p->next=top;top=p;break;}}}}}return 0;}(5)、主函数void main(){struct node *top,*head;top=Initialization();//建立一个链栈,并返回栈顶指针printf("请输入表达式:\n");gets(string1);if(Searchexpression(string1)){head=assort(top);//中缀转化为后缀表达式calcolate(head);}}2、完整函数#include<stdio.h>#include<malloc.h>#include<string.h>#include<stdlib.h>#define MAX 60#define RIGHT 1#define WRONG 0#define DEMAX 15#define NULL 0char string1[MAX];char string2[MAX];int j=0;struct node //定义结构体。