如:4+2*3-10/5的后缀式为:4+23*10 5/-
一 用一个栈将该式的运算进行,并根据后缀式求原表达式.
二 用两个栈表示该表达式,一个栈用存放操作数,另一个用来存放运算符.
四、完善程序:
1.【问题描述】将一个含有运算符为(、)、+、-、*、/、^(乘方运算)、~(求负运算)的中缀表达式转化为后缀表达式。如:((1+2)*5)^2-(3+5)/2转化为12+5*2^35+2/-。
【解题思路】将中缀表达式转化为后缀表达式,首先规定运算符的优先次序如下:
运算符 | ( | ) | +、- | *、/ | ~ | ^ |
优先数 | 0 | 1 | 2 | 3 | 4 | 5 |
①若输入是运算量,则将该运算量输出;
②若是左括号“(”,则将该符号的优先数压入设置的运算符堆栈e[p]中去;
③输入运算符优先数是2、3、4、5时,如果栈空,则将运算符的优先数进栈;如果栈不空,则将它与栈顶元素进行比较,若优先数大于栈顶元素的优先数,则进栈,小于栈顶元素的优先数,则栈顶元素退栈并输出该运算符,然后继续比较,直到大于栈顶元素的优先数或栈空时进栈;
④若是右括号“)”,同时栈顶元素又为左括号“(”,则栈顶元素退栈,并抹去右括号“)”,否则转3处理;
⑤输入完而栈非空,则将栈内内容逐一退栈并输出。所有输出的结果就是后缀表达式。
过程中用到的数据结构如下:
type arraydata=array[1..100] of string[20]
const fh:array[1..8] of string[1]=(‘)’,‘(’,‘+’,‘-’,‘*’,‘/’,
‘~’, ‘^’);
b:array[1..8] of byte=(0,1,2,2,3,3,4,5);
var d:arraydata;{存储运算量及运算符}
i,j,m,k:byte;
【过程程序】procedure hzbds(var d:arraydata;var m:byte);
var e:array[1..100] of byte;
i,p,k,bj:byte;
bl:boolean;
begin
p:=0;k:=1;bj:=0;
while k<=m do
begin
if ① then
begin
p:=p+1;e[p]:=1
end
else
begin
for i:=2 to 8 do
if ② then
begin
b1:=true;
repeat
if ③ then
begin
p:=p+1;e[p]:=i;bj:=1;b1:=false
end
else if ④ then
if e[p]<>1 then
begin
p:=p+1;e[p]:=i;
bj:=1;b1:=false
end
else if d[k]<>‘)’then
begin
p:=p+1;e[p]:=i;
bj:=1;b1:=false
end
else begin
⑤ ;
bj:=1;b1:=false
end
else begin
write(fh[e[p]],‘ ’);p:=p-1
end;
until b1=false;
end;
if ⑥ then write(d[k],‘ ’)
else bj:=0;
end;
k:=k+1;
end;
b1:=true;
repeat
if p=0 then b1:=false
else begin ⑦ ;p:=p-1; end;
until b1=false;
writeln;
end.
#include "lianzhan.h" #include<stdlib.h> #include<iostream> using namespace std; class Calculator{ stack<int> Nstack; stack<char> Ostack; public: void Cal(); void GetNum(int &num1,int &num2); void Computer(char opr); void Cear(); }; void Calculator::Cear(){ Nstack.MakeEmpty(); Ostack.MakeEmpty(); } void Calculator::GetNum(int &num1,int &num2){ num1=Nstack.pop(); num2=Nstack.pop(); } void Calculator::Computer(char opr){ int num1,num2; if(opr!='=') GetNum(num1,num2); switch(opr){ case '+':Nstack.push(num2+num1);break; case '-':Nstack.push(num2-num1);break; case '*':Nstack.push(num2*num1);break; case '/':Nstack.push(num2/num1);break; case '=':cout<<Nstack.pop()<<endl; } } void Calculator::Cal(){ bool b1=true,b2=true; char c1,c2,str[100]; int k=-1; while(b2){ cin>>c1; if(c1>='0'&&c1<='9'){ k++; str[k]=c1; } else{ if(k>=0) { str[k+1]='\0'; Nstack.push(atoi(str)); k=-1; } switch(c1){ case 'c': Cear();break; case '+': case '-': while(!Ostack.IsEmpty()){ c2=Ostack.pop(); Computer(c2); } Ostack.push(c1); break; case '*': case '/': while(!Ostack.IsEmpty()&&b1){ c2=Ostack.pop(); if(c2=='*'||c2=='/') Computer(c2); else{ Ostack.push(c2); b1=false; } } Ostack.push(c1); b1=true; break; case '=': while(!Ostack.IsEmpty()){ c2=Ostack.pop(); Computer(c2); } Computer(c1); break; } if(c1=='z') b2=false; } } delete []str; } void main() {Calculator cal; cal.Cal(); } //lianzhan.h
#include<iostream> #include<assert.h> using namespace std; template<typename T>class stack; template<typename T>class Node{ T info; Node<T> *link; public: Node(T data=0,Node<T> *next=NULL){ info=data; link=next;} friend class stack<T>; }; template<typename T>class stack{ Node<T> *top; public: stack(){top=NULL;} ~stack(); void MakeEmpty(); void push(T data); T pop(); bool IsEmpty()const {return top==NULL;} }; template<typename T>stack<T>::~stack(){ MakeEmpty(); } template<typename T>void stack<T>::MakeEmpty(){ Node<T> *temp; while(top!=NULL) { temp=top; top=top->link; delete temp; } } template<typename T>void stack<T>::push(T data){ top=new Node<T>(data,top); } template<typename T>T stack<T>::pop(){ assert(!IsEmpty()); Node<T> *temp; temp=top; T data=temp->info; top=top->link; delete temp; return data; }