您的位置:首页 > 其它

中序表达式转换为逆波兰表达式

2013-11-04 18:14 267 查看
中序表达式转换为逆波兰表达式,实现了基本的加减乘除以及括号的应用。

将一个普通的中序表达式转换为逆波兰表达式的一般算法是:首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆波兰式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:(1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈(2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。(3)若取出的字符是“(”,则直接送入S1栈栈顶。(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。(5)重复上面的1~4步,直至处理完所有的输入字符(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。完成以上步骤,S2栈便为逆波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆波兰式的计算方法计算了!

#include<iostream>
using namespace std;
#define MaxSize 100
#define MaxOp 7
struct{
char ch;
int pri;
}
lpri[] = {{'=',0},{'(',1},{'*',5},{'/',5},{'+',3},{'-',3},{')',6}},
rpri[] = {{'=',0},{'(',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}};
int leftpri(char op){
int i;
for(i=0;i<MaxOp;i++)
if(lpri[i].ch == op)
return lpri[i].pri;
}
int rightpri(char op){
int i;
for(i=0;i<MaxOp;i++)
if(rpri[i].ch == op)
return rpri[i].pri;
}
int InOp(char ch){
if(ch == '(' || ch == ')' ||ch == '+' || ch == '-' || ch == '*' || ch == '/')
return 1;
else
return 0;
}
int Precede(char op1,char op2){
if(leftpri(op1) == rightpri(op2))
return 0;
else if(leftpri(op1) < rightpri(op2))
return -1;
else
return 1;
}
void trans(char * exp,char postexp[]){
struct{
char data[MaxSize];
int top;
}op;
int i=0;
op.top=-1;
op.top++;
op.data[op.top]='=';
while(* exp != '\0'){
if(!InOp(* exp)){
while(* exp >= '0' && * exp <= '9'){
postexp[i++] = * exp;
exp++;
if(* exp == '.'){
postexp[i++] = * exp;
exp++;
}
}
postexp[i++]='#';
}
else{
switch(Precede(op.data[op.top],* exp)){
case -1:
op.top++;
op.data[op.top] = * exp;
exp++;
break;
case 0:
op.top--;
exp++;
break;
case 1:
postexp[i++] = op.data[op.top];
op.top--;
break;
}
}
}
while(op.data[op.top] != '='){
postexp[i++] = op.data[op.top];
op.top--;
}
postexp[i] = '\0';
}
float calculated(char * postexp){
struct{
float data[MaxSize];
int top;
}st;
float d,a,b,c,e,f;
st.top=-1;
while(* postexp != '\0'){
switch(* postexp){
case '+':
a=st.data[st.top];
st.top--;
b=st.data[st.top];
st.top--;
c=a+b;
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;
st.top++;
st.data[st.top]=c;
break;
case '*':
a=st.data[st.top];
st.top--;
b=st.data[st.top];
st.top--;
c=a*b;
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{
cout<<"除零错误!"<<endl;
exit(0);
}
break;
default:
d=0;
e=0;
f=0;
while(* postexp >= '0' && * postexp <= '9'){
d=10 * d+ *postexp-'0';

4000
postexp++;
if(* postexp == '.'){
postexp++;
while(* postexp >= '0' && * postexp <= '9'){
f++;
e=e * 10 + *postexp-'0';
postexp++;
}
for(int i=0;i<f;i++)
e=e/10;
}
}
d=d+e;
st.top++;
st.data[st.top]=d;
break;
}
postexp++;
}
return st.data[st.top];
}
int main(){
char exp[MaxSize];
char postexp[MaxSize];
float value = 0;
cout<<"请输入你要计算的式子:";
cin>>exp;
trans(exp,postexp);
cout<<"转换成后缀表达式为:"<<postexp<<endl;
value = calculated(postexp);
cout<<"计算结果为:"<<value<<endl;
return 0;
}


本文出自 “淡定的dreamer” 博客,请务必保留此出处http://idiotxl1020.blog.51cto.com/6419277/1288623
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: