使用栈来计算算术表达式

来源:互联网 发布:3d2015历史开奖数据 编辑:程序博客网 时间:2024/06/05 16:20

之所以写这个,是因为最近在学习C++的过程中,C++primer 第五版 9.6的习题跟这个有关,在网上看看些人的思路,也就做出来了,正好写到博客里面。

原题如下:

使用 stack 处理括号化的表达式。当你看到一个左括号,将其记录下来。当你在一个左括号之后看到一个右括号,从 stack 中 pop 对象,直至遇到左括号,

将左括号也一起弹出栈。然后将一个值(括号内的运算结果)push 到栈中,表示一个括号化的(子)表达式已经处理完毕,被其运算结果所替代。

题目也给了思路,具体上代码:

#include "stdafx.h"#include<iostream>#include<queue>#include<vector>#include<string>#include<stack>using namespace std;vector<string>prase(char *str)  //分离每个符号{vector<string>tokens;int len = strlen(str);char *p = (char*)malloc((len + 1) * sizeof(char));int i = 0, j = 0;while (i < len) //去除空格{if (str[i] == ' '){i++;continue;}p[j++] = str[i++];}p[j] = '\0';j = 0;len = strlen(p);while (j < len){char temp[2] = { 0 }; //存储符号string token;switch (p[j]){case '+':case '*':case '/':case '(':case ')':temp[0] = p[j];temp[1] = '\0';token = temp;tokens.push_back(token);break;case '-':if (p[j - 1] == ')' || isdigit(p[j - 1])) //不能使用--j,会死循环{temp[0] = p[j];temp[1] = '\0';token = temp;tokens.push_back(token);break;}else{temp[0] = '$';temp[1] = '\0';token = temp;tokens.push_back(token);break;}default:i = j;while (isdigit(p[i]))i++;char *operand = (char*)malloc((i - j + 1) * sizeof(char));memset(operand, 0, i - j + 1);memcpy(operand, p + j, i - j);operand[i - j] = '\0';token = operand;tokens.push_back(token);free(operand);j = i - 1;break;}j++;}free(p);return tokens;}int priority(string opd){int level;if (opd == "$")level = 3;else if (opd == "*" || opd == "/")level = 2;else if (opd == "+" || opd == "-")level = 1;else if (opd == "(" || opd == ")")level = 0;return level;}void calculate(stack<int>& opdStack, string opt){if (opt == "+"){int rOpd = opdStack.top();opdStack.pop();int lOpd = opdStack.top();opdStack.pop();int result = rOpd + lOpd;opdStack.push(result);}else if (opt == "-"){int rOpd = opdStack.top();opdStack.pop();int lOpd = opdStack.top();opdStack.pop();int result = lOpd - rOpd;opdStack.push(result);}else if (opt == "*"){int rOpd = opdStack.top();opdStack.pop();int lOpd = opdStack.top();opdStack.pop();int result = lOpd * rOpd;opdStack.push(result);}else if (opt == "/"){int rOpd = opdStack.top();opdStack.pop();int lOpd = opdStack.top();opdStack.pop();int result = lOpd / rOpd;opdStack.push(result);}else if (opt == "$"){int result = opdStack.top();opdStack.pop();result = -result;opdStack.push(result);}}int computationalExp(char *str){vector<string>tokens = prase(str);stack<int>opdStack;stack<string>optStack;for (int i = 0; i < tokens.size(); i++){string token = tokens[i];if (token == "+" || token == "-" || token == "*" || token == "/" || token == "$"){if (optStack.empty()){optStack.push(token);}else{int tokenPriority = priority(token);string topOptStack = optStack.top();int optPriority = priority(topOptStack);if (tokenPriority > optPriority) //运算操作符优先于栈顶操作符,则入栈{optStack.push(token);}else{//否则弹出操作符和操作数进行计算,直至当前操作符优先栈顶操作符时,入栈while (tokenPriority <= optPriority){calculate(opdStack, topOptStack);optStack.pop();if (optStack.size() > 0){topOptStack = optStack.top();optPriority = priority(topOptStack);}else{break;}}optStack.push(token);}}}else if (token == "("){optStack.push(token);}else if (token == ")"){while (optStack.top() != "("){string topOpt = optStack.top();calculate(opdStack, topOpt);optStack.pop();}optStack.pop();//弹出"("}else{opdStack.push(stoi(token));//操作数入栈}}while (optStack.size() != 0){string topOpt = optStack.top();calculate(opdStack, topOpt);optStack.pop();}return opdStack.top();}int main(){char *str = "3+5-6*-9/3+(4+3*7)";cout << computationalExp(str) << endl;return 0;}
如有啥问题,请多多指教。