/* 四则运算表达式 1. 如果是运算量,则直接写入数据队列 2. 如果是左括号"(",则直接压入符号栈; 3. 如果是右括号")",则不断弹出符号栈数据,并写入数据队列,直到左括号弹出; 4. 如果是普通运算符,则与栈顶符号比较优先级,如果大于栈顶符号优先级,则入栈; 否则弹出栈顶符号并写入数据队列,直到栈顶符号的运算符优先级较小为止,并且将当前运算符压入栈中; 5. 如果是结束符(表示表达式已全部读完),则符号栈全部弹出并写入存储器,否则读取数据进入下个过程。 */ #include <stdio.h> #include <stdlib.h> #include <iostream> #include <stack> #include <queue> using namespace std; int RetSymbol(char c) { int nRet = 0; switch (c) { case '#': nRet = 0; break; case '+': nRet = 3; break; case '-': nRet = 3; break; case '*': nRet = 4; break; case '/': nRet = 4; break; default: break; } return nRet; } double Operate(double a, double b, char c) { double nRet = 0.0; switch (c) { case '+': nRet = a + b; break; case '-': nRet = a - b; break; case '*': nRet = a * b; break; case '/': nRet = a / b; break; } return nRet; } int main(void) { stack<char> stackSymbol;//放置运算符的栈 queue<char> queueData;//放置运算数据的队列 stack<double> RetData;//放置最终运算结果的栈 char strExpress[40] = {0};//需要计算的表达式 cin>>strExpress; if (!strExpress) { cout<<"Express is NULL!/n"; return -1; } char *pTemp = strExpress; stackSymbol.push('#'); while (*pTemp) { if (*pTemp >= '1' && *pTemp <= '9') {//如果为运算数据,直接存入运算数据队列 queueData.push(*pTemp); } else if (*pTemp == '(') {//如果为左括号,直接入栈 stackSymbol.push(*pTemp); } else if (*pTemp == ')') {//如果为右括号,则按照规则将运算符出栈。 while (stackSymbol.top() != '(') { char temp = stackSymbol.top(); stackSymbol.pop(); queueData.push(temp); } stackSymbol.pop(); } else {//如果为普通四则运算符,则按照规则入栈和出栈 while (RetSymbol(*pTemp) <= RetSymbol(stackSymbol.top()))// { char temp = stackSymbol.top(); stackSymbol.pop(); queueData.push(temp); } stackSymbol.push(*pTemp); } ++pTemp; } while (!stackSymbol.empty()) {//将运算符栈中所有剩余的运算符都弹出到运算数据队列中 char temp = stackSymbol.top(); stackSymbol.pop(); queueData.push(temp); } //打印逆波兰式 int nSize = queueData.size(); queue<char> queueTemp = queueData; for (int i = 0; i < nSize; ++i) { printf("%c", queueTemp.front()); queueTemp.pop(); } cout<<endl; //下面开始计算表达式的值 double nLeft = 0.0, nRight = 0.0; while(queueData.size() > 1.) { if (queueData.front() >= '1' && queueData.front() <= '9' ) { double nTemp = queueData.front() - 48; RetData.push(nTemp); queueData.pop(); } else if (queueData.front() != '#') { nLeft = RetData.top(); RetData.pop(); nRight = RetData.top(); RetData.pop(); char cTemp = queueData.front(); double nTemp = Operate(nRight, nLeft, cTemp); RetData.push(nTemp); queueData.pop(); } } cout<<strExpress<<"="<<RetData.top()<<endl; return 0; }