逆波兰表达式

来源:互联网 发布:js清空select选中的值 编辑:程序博客网 时间:2024/05/22 01:32

逆波兰表达式又叫做后缀表达式。它的语法规定,表达式必须以逆波兰表达式的方式给出。

正常的表达式 逆波兰表达式
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a=1,3 +

(1-2)*(3+6)---> 1,2,-,3,6,+,*

利用栈的知识,可以将逆波兰表达式的值求出。


代码:目前只能计算0-9以内的包含括号的加减乘除,十几二十甚至浮点数的计算有待进一步开发

主要问题是:一个字符串存储逆波兰表达式,包含数字,和字符,很难统一到一起。还有数据长度的问题,目前的代码统一是1位,这样最容易实现。

#include <iostream>#include <string>#include <stack>using namespace std;#define maxsize 100// 获取操作符的优先级int precedence(char op){switch(op){case '^': return 3;    case '*':case '/':case '%': return 2;   case '+':case '-': return 1;   case '(': return 0;}}//判断是否是操作符 int IsOperator(char ch){switch(ch){case '^':case '*':case '/':case '%':case '+':case '-': return 1;   default: return 0;}}// 转换void exchange(char *pSource, char *pDest){char oper[maxsize]; // 定义操作符栈int top = -1; // 初始化栈定位置char ch;if(pSource==NULL || pDest==NULL)return;oper[++top] = '('; // ‘(' 初始化栈while((ch = *pSource++) != '#'){if(ch == '(') // '(' 直接入栈{oper[++top] = ch;}else if(ch == ')') // 运算符出栈拷入目标数组,直到'('{while(oper[top] != '('){ *pDest++ = oper[top--];}top--;}else if(IsOperator(ch)) {if(precedence(ch) > precedence(oper[top])) // 优先级大与栈顶字符,直接入栈{oper[++top] = ch;}else // 优先级小与栈顶字符,所有优先级大的字符拷入目标数组,再入栈{while(precedence(oper[top]) >= precedence(ch)){*pDest++ = oper[top--];}oper[++top] = ch;}}else // 不是运算符直接拷入目标数组{*pDest++ = ch;}}while(top != 0) // 源数组遍历完毕,栈中操作符拷入目标数组{   *pDest++ = oper[top--];}*pDest = '#';}int calculate(char *c,int len)//根据逆波兰表达式,求解值{stack<int> s;//声明一个栈int i=0;int p;int m=0,n=0;while(i<len){if(c[i]=='+'||c[i]=='-'||c[i]=='*'||c[i]=='/'){m=s.top();s.pop();n=s.top();s.pop();if(c[i]=='+'){s.push(m+n);}if(c[i]=='-'){s.push(n-m);}   if(c[i]=='*'){s.push(m*n);}if(c[i]=='/')  {s.push(n/m);}}else{p=c[i]-'0';s.push(p);}i++;}if(s.size()!=1){cout<<"表达式错误"<<endl;return 0;}return s.top();}int main(){string s;getline(cin,s);char X[maxsize];int i=0;int len=s.length();for(i=0;i<len;i++){X[i]=s[i];}X[i]='#';//"3*2^(4+2*2-1*3)-5#";char B[maxsize];exchange(X, B);for(i=0; B[i]!='#'; i++){cout<<B[i];}cout<<endl;//以上是给了例子求逆波兰表达式,比如(1-2)*(4+5)输出 12-45+*//以下是根据逆波兰表达式求值int lenb=i;cout<<calculate(B,lenb)<<endl;return 0;}


0 0
原创粉丝点击