您的位置:首页 > 其它

CSUFT 编译原理实验三 中缀表达式转逆波兰表达式求值

2016-06-23 12:48 369 查看
下面代码是完整版的 加入了单目减运算(即'-'负号 代码中用@符号代替)、浮点数运算、乘方运算。

要用自己写的模板化代码可以参考下面链接 http://blog.csdn.net/geekcoder/article/details/6829386
#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>

using namespace std;

bool isOperator(char op)
{
switch(op)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '@':
return 1;
default :
return 0;
}
}

int priority(char op)
{
switch(op)
{
case '#':
return -1;
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
case '@':
return 4;
default :
return -1;
}
}
//   把中缀表达式转换为后缀表达式,返回后缀表达式的长度(包括空格)
void postfix(char pre[] ,char post[],int &n)
{
int i = 0 ,j=0;
stack<char>st;
// 初始化存储操作符的栈

st.push('#');    // 首先把结束标志‘#’放入栈底

while(pre[i]!='#')
{
if((pre[i]>='0' && pre[i] <='9')||pre[i] =='.') // 遇到数字和小数点直接写入后缀表达式
{
post[j++] = pre[i];
n++;
}
else if (pre[i]=='(')   // 遇到“(”不用比较直接入栈
st.push(pre[i]);
else if(pre[i] ==')')  // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式
{
while(st.top()!='(')
{
char t = st.top();
st.pop();
post[j++] = t;
n++;
}
st.pop(); // 将“(”出栈,后缀表达式中不含小括号
}
else if (isOperator(pre[i]))
{
post[j++] = ' '; // 用空格分开操作数(
n++;
while(priority(pre[i]) <= priority(st.top()))
{
// 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程
char t = st.top();
st.pop();
post[j++] = t;

n++;
}

st.push(pre[i]); // 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈
}

i++;
}
while(!st.empty()) // 将所有的操作符加入后缀表达式
{
post[j++] = st.top();
st.pop();
n++;
}
}

double read(char str[],int *i)
{
double x=0.0;
int k = 0;
while(str[*i] >='0' && str[*i]<='9')  // 处理整数部分
{
x = x*10+(str[*i]-'0');
(*i)++;
}

if(str[*i]=='.') // 处理小数部分
{
(*i)++;
while(str[*i] >= '0'&&str[*i] <='9')
{
x = x * 10 + (str[*i]-'0');
(*i)++;
k++;
}
}
while(k!=0)
{
x /= 10.0;
k--;
}

return x;
}

double postfix_value(char post[])
{
stack<double>st;    // 操作数栈

int i=0 ;
double x1,x2;

while(post[i] !='#')
{
if(post[i] >='0' && post[i] <='9')
st.push(read(post,&i));
else if(post[i] == ' ')
i++;
else if (post[i] =='+')
{
x2 = st.top();
st.pop();
x1 = st.top();
st.pop();
st.push(x1+x2);
i++;
}
else if (post[i] =='-')
{
x2 = st.top();
st.pop();
x1 = st.top();
st.pop();
st.push(x1-x2);
i++;
}
else if (post[i] =='*')
{
x2 = st.top();
st.pop();
x1 = st.top();
st.pop();
st.push(x1*x2);
i++;
}
else if (post[i] =='/')
{
x2 = st.top();
st.pop();
x1 = st.top();
st.pop();
st.push(x1/x2);
i++;
}
else if (post[i] =='^') //乘方运算符
{
x2 = st.top();
st.pop();
x1 = st.top();
st.pop();
double t = pow(x1,x2);
st.push(t);
i++;
}
else if (post[i] =='@') //单目-运算符用@代替

{
x2 = st.top();
st.pop();
x2 = 0-x2;
st.push(x2);
i++;
}
}
return st.top();
}

int  main()
{
stack<int>st ;

char exp[100];
cout << "输入表达式(中缀,以#结束):";
cin >> exp;

char post[100] ;

int n =0;           // 返回后缀表达式的长度
postfix(exp,post,n);
cout <<"逆波兰表达式为:";
for( int i =0 ;i < n ;i++)
cout << post[i] ;

cout << "\n由逆波兰表达式计算出的数值结果:  ";
cout << postfix_value(post) << endl;

return 0;
}


View Code

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: