CSUFT 编译原理实验三 中缀表达式转逆波兰表达式求值
下面代码是完整版的 加入了单目减运算(即'-'负号 代码中用@符号代替)、浮点数运算、乘方运算。
要用自己写的模板化代码可以参考下面链接 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; }
It is loneliness that make you different,not gregariousness