表达式求值
HJ54 表达式求值
题目:
给定一个字符串描述的算术表达式,计算出结果值。
示例
输入:
400+5
输出:
405
解题方法:递归调用
这里细节比较多:
1、数据为负数
2、数据为超过9的数,如12,需要正确转换
3、遇到多重括号的时候,递归处理
代码
#include <cctype>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//几个细节:1、负号和减号全部转成加号+负数来计算
//2、多对括号,采用迭代的方法求解子问题
int compute(string s, int left, int right){
//括号计算的初始变量
char op = '+';
int num = 0;
vector<int> numVec;
for(int i = left; i <= right; i++){
if(isdigit(s[i])){
num = num * 10 + s[i] - '0';
}
if(s[i] == '('){
int layer = 0;
int j = i;
while(j <= right){
if(s[j] == '('){
layer++;
}else if(s[j] == ')'){
layer--;
if(layer == 0)
break;
}
j++;
}
num = compute(s, i + 1, j - 1);
i = j + 1;
}
if(!isdigit(s[i]) || i == right){
switch (op) {//这里op是上一个符号
case '+': numVec.push_back(num); break;
case '-': numVec.push_back(-num);break;
case '*': numVec.back() *= num;break;
case '/': numVec.back() /= num;break;
}
op = s[i];//将当前符号赋值给op,作为下一次的运算符号
num = 0;//每次遇到符号,就重置num的值
}
}
int res = 0;
for(auto i : numVec){
res += i;
}
return res;
}
int main() {
string s;
cin >> s;
cout << compute(s, 0, s.size() - 1) << endl;
}
// 64 位输出请用 printf("%lld")
总结
1、numVec存储正负数,解决了多重减号变正号的问题。因为之前自己用双栈来实现的时候,符号栈中连续的负号的处理会出现负负得正的问题。方法有问题,所以重新按照newcode官方给的思路写。
2、op和num的前置值很重要,在遇到负数时就比较好处理。在计算数据时,op存的是上一个符号。数据计算完成后,再把当前的符号赋值给op,用于下一次符号计算,这样保证了双目运算符取到两个操作数后才开始计算。
写的有些绕,下次再看到这题的时候,需要调试代码估计才能看懂。
3、需要注意迭代的条件和迭代后,i,j的更新
作者:水水滴答
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。