后缀表达式求值的算法及代码
计算后缀表达式的过程(C#)

计算后缀表达式的过程(C#)
计算后缀表达式的过程是⼀个很好玩的过程,⽽且很简单哦!这⾥呢,有个计算的技巧,就是:遇到数字直接⼊栈,遇到运算符就计算!
后缀表达式也叫逆波兰表达式,求值过程可以⽤到栈来辅助存储;
假定待求值的后缀表达式为:12 4 + 13 - 6 2 * + =
求计算出最终结果:
(1)⾸先我们看到在第⼀个运算符之前呢,有两个数字,那么我们就先把它放⼊栈中:
注:我们可以看到,下标是从下⽅开始读的,⼀定要注意哦,不要弄反了
(2)读到“+”,则弹出12和4,执⾏相加,12+4,=16,并把16放进栈中:(先弹12,再弹4,顺序不能弄错了!!)
(3)读到数字“13”,则直接把13放⼊栈内:
(4)读到运算符“-”,则弹出16和13,执⾏相减,那么16-13=3,并把3放⼊到栈中:
注:在这⾥我们可以看到,如果我们把弹出的顺序弄反了,那么得到的数字就会完全不同,那后⾯的结算也会完全不⼀样,所以,弹出的顺序不能弄反了
(5)读到数字“6”,直接⼊栈:
(6)读到数字“2”,直接⼊栈:
(7)读到运算符“*”,弹出6和2,执⾏相乘,6*2=12,并把12放⼊到栈中:
(8)读到运算符“+”,则弹出3和12,执⾏相加,3+12=15,并把15放⼊栈中:
(9)到了这⾥,我们已经把后缀表达式都已经执⾏了⼀遍,那么得到的最后结果为15,故:
12 4 + 13 - 6 2 * + = 15
这就是运算过程,是不是很简单
END。
基于栈的后缀算术表达式求值c语言

基于栈的后缀算术表达式求值c语言1. 引言1.1 概述本文将讨论基于栈的后缀算术表达式求值的实现过程。
后缀算术表达式(也称为逆波兰表达式)是一种无需括号即可进行运算的表达式表示方法,它将操作符置于操作数之后。
相较于传统的中缀表达式,在计算机程序中处理后缀表达式更为高效和简洁。
1.2 文章结构文章分为五个主要部分:引言、栈的概念及原理、后缀算术表达式的定义和转换、基于栈的后缀算术表达式求值算法实现以及结论与总结。
在引言部分,我们将首先介绍本文的概述和目标,对后续内容进行简要说明。
1.3 目的通过本文,我们旨在让读者了解栈数据结构的基本概念和原理,并且掌握如何利用栈来实现对后缀算术表达式进行求值的算法。
同时,我们将介绍后缀算术表达式的定义和转换方法,并给出基于栈实现该计算方式的详细步骤与示例代码。
通过深入研究并学习这些内容,读者可以加深对栈数据结构和后缀算术表达式的理解,并且能够应用所学知识解决实际问题。
本文不仅适用于计算机科学或相关专业的学生,也适合对数据结构和算法感兴趣的读者阅读和学习。
2. 栈的概念及原理2.1 栈的定义栈是一种具有特定限制条件的线性数据结构,它具备“先进后出”(Last-In-First-Out,LIFO)的特性。
栈可以看作是一个容器,其中可以存储各种类型的数据。
与实际生活中的堆栈类似,栈只允许在其末尾进行插入和删除操作。
在栈中,最后加入的元素首先被访问和处理。
这是由于栈内元素之间的相对位置关系决定的。
插入操作称为“压栈”(Push),删除操作称为“弹栈”(Pop),而从栈顶读取元素或获取栈顶元素但不删除它称为“查看”(Peek)。
2.2 栈的基本操作推入元素:将一个元素添加到栈顶。
如果已经存在满员条件,则无法执行此操作。
弹出元素:从栈顶移除一个元素,并返回移除的值。
如果没有任何元素存在,则无法执行此操作。
查看栈顶元素:获取位于栈顶处的元素值,但不对其进行删除。
判断是否为空:检查栈是否为空。
用栈对后缀表达式求值的算法(五种)

⽤栈对后缀表达式求值的算法(五种)转载出处:第⼀种/* 此程序的功能是求出⽤户输⼊的整形表达式的值*//*输⼊的表达式请⽤#结尾,⽐如:2+3+5,应输⼊:2+3+5#。
*/#include <stdio.h>#define MAXSIZE 16typedef struct{int data[MAXSIZE];int top;int base;}seqstack; /* 顺序栈的定义*//*以下为函数声明*/void InitStack(seqstack *);int Empty(seqstack *);void Push(seqstack *, int );int Pop(seqstack *);int GetTop(seqstack *);int Operate(int ,char ,int );char Proceed(char ,char );int In(char );int EvalExpres(void);/* 定义两个栈分别存放运算符和操作数*/seqstack StackR,StackD;/*主函数*/int main(){int v;char ch;while(1){printf("end with #,for example 2+3+5 input:2+3+5#\n");printf("calculate:") ;v = EvalExpres();printf("The result is:%d",v);/*以下为程序控制*/printf("\nInput 'q' to quit and ENTER run again:");do{scanf("%c",&ch);if(ch == 'q' || ch == 'Q')exit(0);}while(ch!='\n');system("cls");}return 0;}void InitStack(seqstack *s){ s->top = 0;s->base = 0;} /* 初始化栈*/int Empty(seqstack *s){ if(s->top == s->base)return 1;elsereturn 0;} /* 判断栈是否为空*/void Push(seqstack *s, int x){if(s->top == MAXSIZE){ printf("OVER FLOW!\n");exit(0);}else{ s->data[s->top] = x;s->top++;}} /* 进栈 */int Pop(seqstack *s){ int e;if(Empty(s)){ printf("Under flow!\n");return 0;} /* 下溢*/else{ s->top--;e = s->data[s->top];return e;}} /* 出栈*/int GetTop(seqstack *s) /*取栈顶元素*/{if(Empty(s)){ printf("Under flow!\n");return 0;}elsereturn s->data[s->top-1];}int EvalExpres(void) /* 表达式求解函数*/{int a,b,i=0,s=0;char c[80],r;InitStack(&StackR);Push(&StackR,'#');InitStack(&StackD);printf(" end with #");gets(c);while(c[i]!='#' || GetTop(&StackR)!='#'){if(!In(c[i])) /* 判断读⼊的字符不是运算符是则进栈*/{ if(c[i] >= '0' && c[i] <= '9'){s += c[i]-'0';while(!In(c[++i])) /*此处实现的功能为当输⼊的数字为多位数时*/{ s*=10;s += c[i]-'0';}Push(&StackD,s+'0');s = 0;}else{printf("wrong!\n");return 0;}}elseswitch(Proceed(GetTop(&StackR),c[i])) /* 此函数⽤来⽐较读取的运算符和栈顶运算符的优先级*/ {case '<': /* 栈顶的元素优先级⾼*/i++;break;case '=': /* 遇到匹配的⼩括号时则去掉他*/Pop(&StackR);i++;break;case '>': /* 栈顶的优先级低则出栈并将结果写⼊栈内*/r = Pop(&StackR);a = Pop(&StackD)-'0';b = Pop(&StackD)-'0';Push(&StackD,Operate(a,r,b)) ;break;}}return (GetTop(&StackD)-'0'); /* 返回运算结果*/}int In(char c) /*问题2:解决In函数问题:判断C是否为运算符是返回1否则返回0*/{char ch[7]={'+','-','*','/','#','(',')'};int i;for(i = 0; i < 7; i++)if(c == ch[i])return 1;return 0;}char Proceed(char op,char c) /*op为栈顶元素,c为当前读⼊的运算符,⽐较⼆者的优先级*/ { /*问题1:解决Proceed函数*/char ch;if(op=='(' && c==')' || op=='#' && c=='#' )ch = '=';elseif(op=='+' || op=='-') /*栈顶元素为‘+’或‘-’的时候*/switch(c){case '+':case '-':case ')':case '#': ch = '>'; break;case '*':case '/':case '(': ch = '<';}elseif(op=='*' || op=='/') /*栈顶元素为‘*’或‘/’的时候*/switch(c){case '+':case '-':case '*':case '/':case ')':case '#': ch = '>'; break;case '(': ch = '<';}elseif(op=='(') /*栈顶元素为‘(’的时候*/switch(c){case '+':case '-':case '*':case '/':case '#': printf("Error!\n"); exit(0);}elseif(op==')') /*栈顶元素为‘)’的时候*/switch(c){case '+':case '-':case '*':case '/':case '#': ch = '>'; break;case '(': printf("Error!\n"); exit(0);}elseif(op=='#') /*栈顶元素为‘#’的时候*/ switch(c){case '+':case '-':case '*':case '/':case '(': ch = '<'; break;case ')': printf("Error!\n"); exit(0);}return ch;}/* 问题3:解决Operate函数*/int Operate(int a,char r,int b) /*返回由aRb的值 */ {int s;int d1 = a;int d2 = b; /*把字符ab变为对应数字*/switch(r){case '+': s = d1+d2; break;case '-': s = d2-d1; break;case '*': s = d1*d2; break;case '/': s = d2/d1;}return (s+'0');}第⼆种#include <stdio.h>#include <malloc.h>#define MaxSize 50void trans(char *exp,char *postexp){struct{char data[MaxSize];int top;} op;int i=0;op.top=-1;while(*exp!='\0'){switch(*exp){case '(':op.top++;op.data[op.top]=*exp;exp++;break;case ')':postexp[i++]=op.data[op.top];op.top--;}op.top--;exp++;break;case '+':case '-':while(op.top!=-1&&op.data[op.top]!='('){postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break; case '*':case '/':while(op.data[op.top]=='*'||op.data[op.top]=='/') {postexp[i++]=op.data[op.top];op.top--;}op.top++;op.data[op.top]=*exp;exp++;break; case ' ':break;default:while(*exp>='0'&&*exp<='9'){postexp[i++]=*exp;exp++;}postexp[i++]='#';}}while(op.top!=-1){postexp[i++]=op.data[op.top];op.top--;}postexp[i]='\0';}float compvalue(char *postexp){struct{float data[MaxSize];int top;} st;float a,b,c,d;st.top=-1;while(*postexp!='\0'){switch(*postexp){case '+':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b+a;st.top++;st.data[st.top]=c;break;case '-':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b-a;break;case '*':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;c=b*a;st.top++;st.data[st.top]=c;break;case '/':a=st.data[st.top];st.top--;b=st.data[st.top];st.top--;if(a!=0){c=b/a;st.top++;st.data[st.top]=c;}else{printf("\n\t除零错误!\n");exit(0);}break;default:d=0;while(*postexp>='0'&&*postexp<='9'){d=10*d+*postexp-'0';postexp++;}st.top++;st.data[st.top]=d;break;}postexp++;}return st.data[st.top];}int main(){char exp[MaxSize],postexp[MaxSize];while(scanf("%s",&exp)!=EOF){trans(exp,postexp);printf("zhongzhuibiaodashi: %s\n",exp);printf("houzuibiaodashi: %s\n",postexp);printf("zhi: %g\n",compvalue(postexp)); }return 0;}第三种#include<stdio.h>#include<stdlib.h>#define add 43#define subs 45#define mult 42#define div 47#define MAXSIZE 100int data[MAXSIZE];int top;}seqstack;seqstack *s;seqstack *Init() /*栈的初始化*/{seqstack *s;s=(seqstack *)malloc(sizeof(seqstack)); if(!s){printf("FULL!");return NULL;}else{s->top=-1;return s;}}int Empty(seqstack *s) /*栈空的判断*/{if(s->top==-1) return 1;else return 0;}int Push(seqstack *s,int x) /*⼊栈*/{if(s->top==MAXSIZE-1) return 0;else{s->top++;s->data[s->top]=x;return 1;}}int Pop(seqstack *s,int *x) /*出栈的算法*/ {if (Empty(s)) return 0;else{*x=s->data[s->top];s->top--;return 1;}}int Top(seqstack *s) /*取栈顶元素*/ {if(Empty(s)) return 0;else return s->data[s->top];}int eval(char t,int a1,int a2){switch(t){case add:return(a1+a2);case subs:return(a1-a2);case mult:return(a1*a2);case div:return(a1/a2);}}void main(){char c;int op1,op2,temp,c1;s=Init();printf("Input:(end with #)\n");while((c=getchar())!='#'){if(c=='')continue;if(c>47&&c<58){putchar(c);c1=c-48;}else if(c==add||c==subs||c==mult||c==div){putchar(c);Pop(s,&op1);Pop(s,&op2);temp=eval(c,op2,op1);Push(s,temp);}else printf("It's wrong!\n");}Pop(s,&op1);printf("=%d\n",op1);getch();}第四种#include<stdio.h>#include<stdlib.h>#define add 43#define subs 45#define mult 42#define div 47#define MAXSIZE 100typedef struct{int data[MAXSIZE];int top;}STKzone;typedef STKzone *STK;typedef enum{ture=1,false=0} bool;typedef enum{ok,error} status;STKzone expSTKzone;STK expSTK;STK initSTK(STKzone *stkzone) /*栈的初始化*/{STK p;p=stkzone;p->top=0;}status push(int *term,STK pstk) /*⼊栈*//*term前可以没有*,同时将第28、71、81⾏稍作修改即可 */ {if(pstk->top==MAXSIZE) return error;pstk->data[pstk->top]=*term;pstk->top++;return ok;}bool emptySTK(STK pstk) /*栈空的判断*/{return (pstk->top==0);}status pop(int *pdata,STK pstk) /*出栈的算法*/{if (emptySTK(pstk)) return error;(pstk->top)--;*pdata=pstk->data[pstk->top];return ok;}void synerror(){printf("\nyu fa cuo wu!");}{switch(tag){case add:return(a1+a2);case subs:return(a1-a2);case mult:return(a1*a2);case div:return(a1/a2);}}main(){ char c;int op1,op2,temp,c1;expSTK=initSTK(&expSTKzone);printf("Input:\n");while((c=getchar())!='\n'){if(c=='')continue;if(c>47&&c<58){putchar(c);c1=c-48;if(push(&c1,expSTK)==error){printf("\n too long!\n");}}else if(c==add||c==subs||c==mult||c==div) {putchar(c);if(pop(&op1,expSTK)==error)synerror(); if(pop(&op2,expSTK)==error)synerror(); temp=eval(c,op2,op1);push(&temp,expSTK);}else synerror();}if(pop(&op1,expSTK)==error) synerror();if(!(emptySTK(expSTK))) synerror();printf("=%d\n",op1);getch();}第五种#include<stdio.h>#include<stdlib.h>#define add 43#define subs 45#define mult 42#define div 47#define MAXSIZE 100typedef struct{int stkdata[MAXSIZE];int top;}stack;int init_stack(stack *s){ s=(stack *)malloc(sizeof(stack));if(!s){printf("FULL!\n");return 0;}else{s->top=-1;return 1;}}int push(stack *s,int x){ printf("over flow\n");return 0;}else{s->top++;s->stkdata[s->top]=x;return 1;}}char pop(stack *s){ char e;if(s->top==-1){printf("under flow \n");return 0;}e=s->stkdata[(s->top)--];return e;}void main(){stack *s1;int length,i,num1,num2,result,sum;char s[100];init_stack(s1);printf("please input \n");printf("warning:must less than 100\n");gets(s);length=strlen(s);for(i=0;i<=length-1;i++){ if(s[i]>='1'&&s[i]<='9')push(s1,s[i]-48);else{ num1=pop(s1);num2=pop(s1);switch(s[i]){case add: {sum=num1+num2;push(s1,sum);break;}case subs:{sum=num2-num1;push(s1,sum);break;}case div:{sum=num2/num1;push(s1,sum);break;}case mult:{sum=num1*num2;push(s1,sum);break;}}}}result=s1->stkdata[s1->top];printf("result is %d\n",result);getch();}在研究表达式。
栈应用之后缀表达式计算(python版)

栈应⽤之后缀表达式计算(python版)栈应⽤之后缀表达式计算(python 版)后缀表达式特别适合计算机处理1. 中缀表达式、前缀表达式、后缀表达式区别 中缀表达式:(3 - 5) * (6 + 17 * 4) / 3 17 * 4 + 6前缀表达式:/ * - 3 5 + 6 * 17 4 3 * 17 4 + 6后缀表达式:3 5 - 6 17 4 * + * 3 / 17 4 * 6 +2. 算法核⼼ 假定 st 是⼀个栈(栈的特点:后进先出 LIFO) ⽐如【3 / 5】即【3 5 / 】; 3 先压⼊栈,⽽后 5 出栈; 元素在栈⾥⾯的顺序应该是【5,3】; 5 先出栈,⽽后 3 出栈。
所以第⼆个运算对象先出栈,第⼀个运算对象后出栈。
1# 扩充栈的⽅法计算栈元素个数2class ESStack(SStack):3"""docstring for ESS"""4def depth(self):5return len(self._elems)1def auf_exp_evaluator(exp):2 operatora = '+-*/'3 st = ESStack() # 扩充功能的栈,可⽤depth()检查元素个数45for x in exp:6if x not in operatora:7 st.push(flaot(x))8continue# 跳过本次for循环910if st.depth() < 2 :11raise SyntaxError{"Short of operand(s)"}12 a = st.pop() # 取出第⼆个运算对象13 b = st.pop() # 取出第⼀个运算对象1415if x == "+":16 c = b + a17elif x == "-":18 c = b - a19elif x == "*":20 c = b * a21elif x == "/" : # 这⾥可能引发异常 ZeroDivisionError22 c = b / a23else :24break# 这⼀步不可能出现,只是为了⽅便看、理解2526 st.push(c) # 将本次运算结果压⼊栈2728if st.depth() == 1 # 如果栈⾥⾯只有⼀个元素,表⽰计算完成29return st.pop()30raise SyntaxError{"Extra operand(s) ."}。
后缀表达式求值的算法及代码

#include<stdlib.h>#include<stdio.h>struct node // 栈结构声明{int data; // 数据域struct node *next; // 指针域};typedef struct node stacklist; // 链表类型typedef stacklist *link; // 链表指针类型link operand=NULL; // 操作数栈指针link push(link stack,int value) // 进栈{link newnode; // 新结点指针newnode=new stacklist; // 分配新结点if (!newnode){printf("分配失败!");return NULL;}newnode->data=value; // 创建结点的内容newnode->next=stack;stack=newnode; // 新结点成为栈的开始return stack;}link pop(link stack,int *value) // 出栈{link top; // 指向栈顶if (stack !=NULL){top=stack; // 指向栈顶stack=stack->next; // 移动栈顶指针*value=top->data; // 取数据delete top; // 吸收结点return stack; // 返回栈顶指针}else*value=-1;}int empty(link stack) // 判栈空{if (stack!=NULL)return 1;elsereturn 0;}int isoperator(char op) // 判运算符{switch (op){case'+':case'-':case'*':return 1; // 是运算符,返回1case'/':return 0; // 不是运算符,返回0}}int getvalue(int op,int operand1,int operand2) // 计算表达式值{switch((char)op){case'*':return(operand1*operand2);case'/':return(operand1/operand2);case'+':return(operand1+operand2);case'-':return(operand1-operand2);}}void main() // 主函数{char exp[100];int operand1=0; // 定义操作数1int operand2=0; // 定义操作数2int result=0; // 定义操作结果int pos=0;printf("\t\n 请输入后缀表达式:");gets(exp); // 读取表达式printf("\t\n\n 后缀表达式[%s]的计算结果是:",exp);while (exp[pos] !='\0' && exp[pos] !='\n') // 分析表达式字符串{if (isoperator(exp[pos])) // 是运算符,取两个操作数{operand=pop(operand,&operand1);operand=pop(operand,&operand2);operand=push(operand,getvalue(exp[pos],operand1,operand2));// 计算结果入栈}elseoperand=push(operand,exp[pos]-48); // 是操作数,压入操作数栈pos++; // 移到下一个字符串位置}operand=pop(operand,&result); // 弹出结果printf("%d\n",result); // 输出}。
C#算术表达式求值(后缀法),看这一篇就够了

C#算术表达式求值(后缀法),看这⼀篇就够了⼀、种类介绍算术表达式有三种:前缀表达式、中缀表达式和后缀表达式。
⼀般⽤的是中缀,⽐如1+1,前后缀就是把操作符移到前⾯和后⾯,下⾯简单介绍⼀下这三种表达式。
1、前缀表⽰法前缀表⽰法⼜叫波兰表⽰法,他的操作符置于操作数的前⾯(例:+ 1 2),是波兰数学家扬·武卡谢维奇1920年代引⼊的,⽤于简化命题逻辑。
因为我们⼀般认为操作符是在操作数中间的,所以在⽇常⽣活中⽤的不多,但在计算机科学领域占有⼀席之地。
⼀般的表⽰法对计算机来说处理很⿇烦,每个符号都要考虑优先级,还有括号这种会打乱优先级的存在,将使计算机花费⼤量的资源进⾏解析。
⽽前缀表⽰法没有优先级的概念,他是按顺序处理的。
举个例⼦:9-2*3这个式⼦,计算机需要先分析优先级,先乘后减,找到2*3,再进⾏减操作;化成前缀表⽰法就是:- 9 * 2 3,计算机可以依次读取,操作符作⽤于后⼀个操作数,遇到减就是让9减去后⾯的数,⽽跟着9的是乘,也就是说让9减去乘的结果,这对计算机来说很简单,按顺序来就⾏了。
2、中缀表⽰法这也就是我们⼀般的表⽰法,他的操作符置于操作数的中间(例:1 + 2),前⾯也说过这种⽅法不容易被计算机解析,但他符合⼈们的普遍⽤法,许多编程语⾔也就⽤这种⽅法了。
在中缀表⽰法中括号是必须有的,要不然运算顺序会乱掉。
3、后缀表⽰法后缀表⽰法⼜叫逆波兰表⽰法,他的操作符置于操作数的后⾯(例:1 2 +),他和前缀表⽰法都对计算机⽐较友好,但他很容易⽤堆栈解析,所以在计算机中⽤的很多。
他的解释过程⼀般是:操作数⼊栈;遇到操作符时,操作数出栈,求值,将结果⼊栈;当⼀遍后,栈顶就是表达式的值。
因此逆波兰表达式的求值使⽤堆栈结构很容易实现,且能很快求值。
注意:逆波兰记法并不是简单的波兰表达式的反转。
因为对于不满⾜交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法/ 6 3的逆波兰记法是6 3 /⽽不是3 6 /;数字的数位写法也是常规顺序。
前缀后缀算数运算编程

一、设计思想1、中缀转化为后缀算法过程中要使用一个栈和两个数组,(栈用来存放运算符,一个数组用来存放中缀表达式,两一个则是存放后缀表达式)表达式的转换过程如下:(1)、将表达式开始符“#“压入运算符栈,作为栈底元素。
(2)、从左到右依次扫描中缀表达式的每一个字符。
(3)、如果遇到的是开括号“(”,则将它们压入一个操作符栈(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“)”时,将栈中的元素弹出来并放入后缀表达式中,直到栈顶元素为“(”时,将栈顶元素“(”弹出(不需要加入后缀表达式),表明这一层括号内的操作处理完毕(4)、即将进栈的操作符要与栈顶的操作符进行优先级比较,若当所遇到的操作符的优先级大于栈顶元素时,进栈,否则是将栈顶元素一次弹栈放入后缀数组,直到比较操作符小于或等于栈顶元素时为止。
重复以上操作,最后将栈内所有操作符放进后缀数组内。
(5)、重复上述步骤直到缀表达式的结束符标记“#“,弹出栈中所有元素并放入后缀表达,转换结束。
中缀表达式为:17-3*4+(8/2)# 后缀表达式为:17 3 4 * - 8 2/+2、中缀转化为前缀算法过程中要使用三个数组,(一个栈数组,一个存放中缀表达式,一个存放前缀表达式)表达式的转换过程如下:(1)将表达式开始符“#“压入运算符栈数组,作为栈底元素。
(2)、从右到左依次扫描中缀表达式的每一个字符。
(3)、如果遇到的是开括号“)”,则将它们放进栈数组内(不需要与栈顶操作符相比较),它表明一个新的计算层次的开始,在遇到和它匹配的闭括号“(”时,将栈中的元素弹出来并放入前缀表达式中,直到栈顶元素为“)”时,将栈顶元素“)”弹出(不需要加入后缀表达式),表明这一层括号内的操作处理完毕(4)、如果遇到的是操作符,则将该操作符和操作符栈顶元素比较:当所遇到的操作符的优先级小于栈顶元素的优先级时,则取出栈顶元素放入后缀表达式,并弹出该栈顶元素,反复执行直到操作符的优先级大于或等于栈顶元素的优先级的时则将它压入栈中。
中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)

中缀表达式变后缀表达式、后缀表达式(逆波兰)求值(python版本)定义:中缀表达式:在通常的表达式中,⼆元运算符总是置于与之相关的两个运算对象之间,这种表⽰法也称为中缀表达式后缀表达式:⼜叫逆波兰表达式,不包含括号,放在两个运算对象的后⾯,所有的计算按运算符出现的顺序,严格从左向右进⾏(不再考虑运算符的优先规则,如:(2 + 1) * 3 ,即2 1 + 3 *⼀个字符串表达式s = “9 + ( 3 - 1 ) * 3 + 10 / 2”)求值的过程分为两步(⼀) 将中缀表达式s变为后缀表达式s_after = "9 3 1 - 3 * + 10 2 / +",具体的规则如下:⾸先维护两个空栈,(stack_exp)存放逆波兰表达式,(stack_ops)暂存操作符,运算结束后stack_ops必为空循环遍历字符串(将表达式分为四种元素 1、数值; 2、操作符; 3、左括号; 4、右括号),具体情况如下1、遇到数值,将该值⼊栈stack_exp2、遇到左括号,将左括号⼊栈stack_ops3、遇到右括号,将stack_ops中的操作符从栈顶依次出栈并⼊栈stack_exp,直到第⼀次遇到左括号终⽌操作(注意:该左括号出栈stack_ops但不⼊栈stack_exp)⾄此消除表达式中的⼀对括号4、遇到四则运算操作符号(+ - * /)4-1、如果stack_ops为空,操作符⼊栈stack_ops4-2、如果stack_ops不空,将stack_ops栈顶操作符与遍历到的操作符(op)⽐较:4-2-1:如果stack_ops栈顶操作符为左括或者op优先级⾼于栈顶操作符优先级, op⼊栈stack_ops,当前遍历结束4-2-2:如果op优先级⼩于或者等于stack_ops栈顶操作符, stack_ops栈顶操作符出栈并⼊栈stack_exp,重复4-1、 4-2直到op⼊栈stack_ops5、字符串遍历结束后如果stack_ops栈不为空,则依次将操作符出栈并⼊栈stack_exppython代码实现如下:ops_rule = {'+': 1,'-': 1,'*': 2,'/': 2}def middle_to_after(s):expression = []ops = []ss = s.split('')for item in ss:if item in ['+', '-', '*', '/']:while len(ops) >= 0:if len(ops) == 0:ops.append(item)breakop = ops.pop()if op == '('or ops_rule[item] > ops_rule[op]:ops.append(op)ops.append(item)breakelse:expression.append(op)elif item == '(':ops.append(item)elif item == ')':while len(ops) > 0:op = ops.pop()if op == '(':breakelse:expression.append(op)else:expression.append(item)while len(ops) > 0:expression.append(ops.pop())return expression(⼆) 将后缀表达式s_after = "9 3 1 - 3 * + 10 2 / +" 求值,具体的规则如下:初始化⼀个空栈stack_value,⽤于存放数值循环s_after1、如果遇到数字,⼊栈stack_value;2、如果遇到运算符,从stack_value中依次出栈两个数(先出栈的在右,后出栈的在左)连同遍历到的运算符组成⼆⽬运算,求值后将结果压栈stack_value3、继续遍历下⼀个元素,直到结束遍历完后stack_value中的结果便是表达式的值python代码实现如下:def expression_to_value(expression):stack_value = []for item in expression:if item in ['+', '-', '*', '/']:n2 = stack_value.pop()n1 = stack_value.pop()result = cal(n1, n2, item)stack_value.append(result)else:stack_value.append(int(item))return stack_value[0]def cal(n1, n2, op):if op == '+':return n1 + n2if op == '-':return n1 - n2if op == '*':return n1 * n2if op == '/':return n1 / n2if __name__ == '__main__':expression = middle_to_after('9 + ( 3 * ( 4 - 2 ) ) * 3 + 10 / 2')value = expression_to_value(expression)print value。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
void main() //主函数
{
char exp[100];
int operand1=0; //定义操作数1
int operand2=0; //定义操作数2
int result=0; //定义操作结果
int pos=0;
printf("\t\n请输入后缀表达式:");
operand=pop(operand,&operand2);
operand=push(operand,getvalue(exp[pos],operand1,operand2));//计算结果入栈
}
else
operand=push(operand,exp[pos]-48); //是操作数,压入操作数栈
}
newnode->data=value; //创建结点的内容
newnode->next=stack;
stack=newnode; //新结点成为栈的开始
return stack;
}
link pop(link stack,int *value) //出栈
{
link top; //指向栈顶
if (stack !=NULL)
{
if (stack!=NULL)
return 1;
else
return 0;
}
int isoperator(char op) //判运算符
{
switch (op)
{
case'+':
case'-':
case'*':return 1; //是运算符,返回1
case'/':return 0; //不是运算符,返回0
}
}
int getvalue(int op,int operand1,int operand2) //计算表达式值{switch((char)op)
{
case'*':return(operand1*operand2);
case'/':return(operand1/operand2);
case'+':return(operand1+operand2);
pos++; //移到下一个字符串位置
}
operand=pop(operand,&result); //弹出结果
printf("%d\n",result); //输出
}
link operand=NULL; //操作数栈指针
link push(link stack,int value) //进栈
{
link newnode; //新结点指针
newnode=new stacklist; //分配新结点
if (!newnode)
{
printf("分配失败!");
return NULL;
{
top=stack; //指向栈顶
stack=stack->next; //移动栈顶指针
*value=top->data; //取数据
delete top; //吸收结点
return stack; //返回栈顶指针
}
else
*value=-1;
}
int empty(link stack) //判栈空
#include<stdlib.h>
#include<stdio.h>
struct node //栈结构声明
{
int data; //数据域
struct node *next; //指针域
};
typedef struct node stacklist; //链表类型
typedef stacklist *link; //链表指针类型
gets(exp); //读取表达式
printf("\t\n\n后缀表达式[%s]的计算结果是:",exp);
while (exp[pos] !='\0' && exp[pos] !='\n') //分析表达式字符串
{
if (isoperator(exp[pos])) //是运算符,取两个操作数
{
operand=pop(operand,&operand1);