表达式计算(双栈实现)
问题:计算下列表达式
1+2*3-4-(2-(-1))*2+4/2
计算中包含+,-,*,/,(,),数字,负号(-)
1 #include <iostream> 2 #include <stack> 3 4 using namespace std; 5 6 bool isOp(string &val, int pos) { 7 if (val[pos] == '-') { 8 if (pos == 0 || (isOp(val, pos-1) && val[pos-1] != ')')) { 9 return false; 10 } 11 } 12 char c = val[pos]; 13 return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')'); 14 } 15 16 int getPriority(char c) { 17 if (c == '(' || c == ')') 18 return 0; 19 else if (c == '+' || c == '-') 20 return 1; 21 else if (c == '*' || c == '/') 22 return 2; 23 return 0; 24 } 25 26 int getResult(int a, int b, char op) { 27 if (op == '+') 28 return a + b; 29 else if (op == '-') 30 return a - b; 31 else if (op == '*') 32 return a * b; 33 else if (op == '/') 34 return a / b; 35 return 0; 36 } 37 38 void calculate(stack<int> &data, stack<char> &op) { 39 char ch = op.top(); 40 int behind = data.top(); 41 data.pop(); 42 int before = data.top(); 43 data.pop(); 44 data.push(getResult(before, behind, ch)); 45 op.pop(); 46 } 47 48 int main() { 49 string val; 50 cin >> val; 51 int result = 0; 52 stack<int> data; 53 stack<char> op; 54 string tmp = ""; 55 for (int i = 0; i < val.length(); ++i) { 56 if (isOp(val, i) ) { 57 if (!tmp.empty()) { 58 data.push(atoi(tmp.c_str())); 59 tmp.clear(); 60 } 61 if (op.empty() || val[i] == '(') { 62 op.push(val[i]); 63 } else { 64 bool bKuoHao = false; 65 while (!op.empty() && getPriority(op.top()) >= getPriority(val[i])) { 66 if (val[i] == ')') { 67 while(!op.empty() && op.top() != '(') { 68 calculate(data, op); 69 } 70 op.pop(); 71 bKuoHao = true; 72 break; 73 } else { 74 calculate(data, op); 75 } 76 } 77 if (!bKuoHao) 78 op.push(val[i]); 79 } 80 } else { 81 tmp += val[i]; 82 if (i == val.length() - 1) { 83 data.push(atoi(tmp.c_str())); 84 tmp.clear(); 85 } 86 } 87 } 88 while(!op.empty()) { 89 calculate(data, op); 90 } 91 cout << data.top() << endl; 92 93 return 0; 94 }
上面的不支持浮点数的计算,所以这里再调整一下数据类型,支持double
可计算浮点数 3.8*2.4-(2.3/1.2)
1 #include <iostream> 2 #include <stack> 3 4 using namespace std; 5 6 //判断是否是运算符 7 bool isOp(string &val, int pos) { 8 if (val[pos] == '-') { 9 if (pos == 0 || (isOp(val, pos-1) && val[pos-1] != ')')) { // 判断是负号就不能当成是运算符,直接写到数字里面 10 return false; 11 } 12 } 13 char c = val[pos]; 14 return (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')'); 15 } 16 17 //计算符号的优先级 18 int getPriority(char c) { 19 if (c == '(' || c == ')') 20 return 0; 21 else if (c == '+' || c == '-') 22 return 1; 23 else if (c == '*' || c == '/') 24 return 2; 25 return 0; 26 } 27 28 //计算函数,通过运算符实行对应的计算 29 double getResult(double a, double b, char op) { 30 if (op == '+') 31 return a + b; 32 else if (op == '-') 33 return a - b; 34 else if (op == '*') 35 return a * b; 36 else if (op == '/') 37 return a / b; 38 return 0; 39 } 40 41 //操作栈计算栈顶的结果并放回栈中 42 void calculate(stack<double> &data, stack<char> &op) { 43 char ch = op.top(); 44 double behind = data.top(); 45 data.pop(); 46 double before = data.top(); 47 data.pop(); 48 data.push(getResult(before, behind, ch)); 49 op.pop(); 50 } 51 52 int main() { 53 string val; 54 while(cin >> val) { 55 stack<double> data; 56 stack<char> op; 57 string tmp = ""; 58 for (int i = 0; i < val.length(); ++i) { 59 if (isOp(val, i) ) { // 如果当前位置表示的是运算符 60 if (!tmp.empty()) { // 如果数字非空,则将数字压到数字栈中 61 data.push(atof(tmp.c_str())); 62 tmp.clear(); 63 } 64 if (op.empty() || val[i] == '(') { // 符号栈空的情况下或者碰到左括号,直接压栈即可 65 op.push(val[i]); 66 } else { 67 bool bKuoHao = false; 68 while (!op.empty() && getPriority(op.top()) >= getPriority(val[i])) { // 当符号栈顶的优先级大于等于当前符号的优先级的时候,则需要先计算栈里面的值 69 if (val[i] == ')') { // 如果当前的符号是右括号,需要特殊处理,计算栈直到遇到左括号结束 70 while(!op.empty() && op.top() != '(') { 71 calculate(data, op); 72 } 73 op.pop(); 74 bKuoHao = true; 75 break; 76 } else { // 否则就是对栈顶的运算符进行计算 77 calculate(data, op); 78 } 79 } 80 if (!bKuoHao) // 括号的情况下不需要压栈 81 op.push(val[i]); 82 } 83 } else { //非运算符及累加起来转换成数字 84 tmp += val[i]; 85 if (i == val.length() - 1) { // 最后一个数字需要特殊处理主动压栈 86 data.push(atof(tmp.c_str())); 87 tmp.clear(); 88 } 89 } 90 } 91 while(!op.empty()) { 92 calculate(data, op); 93 } 94 cout << data.top() << endl; 95 } 96 return 0; 97 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2019-06-24 1033 To Fill or Not to Fill (25 分)
2019-06-24 1032 Sharing (25 分)
2019-06-24 1031 Hello World for U (20 分)
2019-06-24 1030 Travel Plan (30 分)