栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

题目大意

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

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++实现,开始理解栈和递归

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

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947341.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号