牛客题目链接
题目中给出一个字符串来表达一个表达式,使用程序去计算出所得的值
AC代码
#include代码解释#include using namespace std; string origin_value; int position = 0; void input(){ cin >> origin_value; } int get_int(char c){ return c - '0'; } void deal_cmd(stack &opreate_num,char cmd, int num){ switch(cmd){ case '+': opreate_num.push(num); break; case '-': opreate_num.push(-num); break; case '*': opreate_num.top() *= num; break; case '/': opreate_num.top() /= num; break; } } int calculate(stack num){ int sum = 0; while(!num.empty()){ sum += num.top(); num.pop(); } return sum; } int deal_expression(){ int temp_num = 0 , value_len = origin_value.length(); char cmd = '+'; stack opreate_num; // 设置为局部变量(在递归调用时方便) while(position < value_len){ // 这里使用while,直接以全局变量position小于长度作为循环条件 if(origin_value[position] == '('){ // 遇到"()"递归调用 // ()先执行,但是运算符执行顺序和外部的一致 position ++; temp_num = deal_expression(); } while(position < value_len && isdigit(origin_value[position])){ temp_num = temp_num * 10 + get_int(origin_value[position]); position ++; } deal_cmd(opreate_num, cmd, temp_num); temp_num = 0; cmd = origin_value[position]; if(origin_value[position] == ')'){ position ++; break; } position ++; } return calculate(opreate_num); } int main(){ input(); cout << deal_expression(); return 0; }
输入
首先进行输入。为便于后续修改输入格式和检查输入,特地封装成input函数
void input(){
cin >> origin_value;
}
处理表达式
在输入完成后,需要进行处理表达式
首先在函数内定义变量
- temp_num:每一次计算所得的值(临时需要),之后会存入栈保存
- value_len:字符串的长度,循环的终止条件
- cmd:检测到的四则运算,默认为+
- opreate_num:特地设置为局部变量,方便在处理()运算符时,进行新的操作数的存储
定义完变量后,执行主要逻辑
首先----处理()运算
首先需要处理的就是()的运算,直接递归调用自身
因为函数最后会返回当前表达式的值,且遇到(时递归调用自身,遇到)结束调用,返回值
if(origin_value[position] == '('){
// 遇到"()"递归调用
// ()先执行,但是运算符执行顺序和外部的一致
position ++;
temp_num = deal_expression();
}
if(origin_value[position] == ')'){
position ++;
break;
}
处理数
判断position是否合法,且当前是数字则进行数字的运算
也就是将所有符号前的数字算出来
while(position < value_len && isdigit(origin_value[position])){
temp_num = temp_num * 10 + get_int(origin_value[position]);
position ++;
}
处理四则运算表达式
判断cmd对应的符号
- +:直接将num存入即可
- -:存入num的相反数
- *:将栈顶元素 *= 当前num
- /:将栈顶元素 /= 当前num
void deal_cmd(stack&opreate_num,char cmd, int num){ switch(cmd){ case '+': opreate_num.push(num); break; case '-': opreate_num.push(-num); break; case '*': opreate_num.top() *= num; break; case '/': opreate_num.top() /= num; break; } }
处理完成后,将temp_num置为0,运算符号更新
返回值
由于在处理四则运算时,存入栈时就已经操作完成
所以在返回值时,只需将栈中的所有元素相加即可!
int calculate(stack总结与分析num){ int sum = 0; while(!num.empty()){ sum += num.top(); num.pop(); } return sum; }
在看见这一题的时候,我感觉很简单,但是就有些不知道该怎么入手,然后尝试使用python去实现
一行代码解决……
但是终究还是不知道内部如何实现的,于是还是反过头来去使用c++实现,开始理解栈和递归
首先很自然的想到,当遇到括号时可以重新递归调用自己去记录值
因为括号的内部四则运算也是和外部一致,仅仅只是内部的先执行出来结果而已
而且每次最后运算的值,都需要加入到栈中。在将数据存入栈中的时候,也可对数据进行预处理。对于减运算符,直接存入负数,乘和除法运算则直接可以修改栈顶元素即可!



