表达式求值【栈和递归的使用】

题目大意

牛客题目链接
题目中给出一个字符串来表达一个表达式,使用程序去计算出所得的值

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<int> &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<int> 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<int> 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<int> &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<int> num){
    int sum = 0;
    while(!num.empty()){
        sum += num.top();
        num.pop();
    }
    return sum;
}

总结与分析

在看见这一题的时候,我感觉很简单,但是就有些不知道该怎么入手,然后尝试使用python去实现
一行代码解决……
表达式求值【栈和递归的使用】_第1张图片

但是终究还是不知道内部如何实现的,于是还是反过头来去使用c++实现,开始理解栈和递归

首先很自然的想到,当遇到括号时可以重新递归调用自己去记录值

因为括号的内部四则运算也是和外部一致,仅仅只是内部的先执行出来结果而已

而且每次最后运算的值,都需要加入到栈中。在将数据存入栈中的时候,也可对数据进行预处理。对于减运算符,直接存入负数,乘和除法运算则直接可以修改栈顶元素即可!

你可能感兴趣的:(PTA,c++,算法,开发语言)