LeetCode 计算器问题

解析字符串实现计算器功能

227. 基本计算器 II

给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。

字符串里可能含有空格。Link

  • 加减存储结果、乘除立即运算
  • 在开头增加运算符+,实现「运算符、数字」的对子形式
  • 「+ 2 + 3 * 4 - 5 / 6 + 3」,初始化左、右为 0
    • 加、减则将右值加到左值上,并更新右值
    • left += right (0 += 0); right = ±num (2)

    • left = 0, right = 2; left = 2, right = 3;

    • 乘除则立即对右值进行运算,并更新右值
    • left = 2, right = 3 * 4 = 12;

    • left = 14, right = -5; left = 14, right = 0

    • left = 14, right = 3

  • 最后返回 left + right
class Solution {
public:
    int calculate(string s) {
        int i = 0;
        return parseExptr(s, i);
    }
    int parseExptr(string& s, int& i) {
        char op = '+';
        int num = 0;
        int left = 0, right = 0;
        while(i < s.size()) {
        	char c = s[i];
            if (isdigit(c)) {
                num = num * 10 + (c- '0');
            }
            // c 为运算符 或 已经到达了表达式的末尾
            // ‘+’ 2 + 3 * 4 - 5 / 6 + 3
            // 当符号 c 为 + 时才会将 ’+‘ 2 这个对子进行计算
            // 所以到达表达式的末尾,必须进行计算,否则末尾的 + 3 结果将丢弃
            if ((!isdigit(c) && c != ' ') || i == s.size() - 1) {
                switch(op) {
                    case '+' : left += right; right = num; break;
                    case '-' : left += right; right = -num; break;
                    case '*' : right *= num; break;
                    case '/' : right /= num; break;
                    default: break;
                }
                op = c;
                num = 0;
            }
            i++; // 继续取下一个字符
        }
        return left + right;
    }
};

224. 基本计算器

772. 基本计算器 III

包含了括号的计算器,同时可能含有空格

  • 遇 ‘(’ 则递归、遇 ‘)’ 则返回
  • 「2*(5+5*2)+(6/2+8) + 5」》 「2 * cal(5 + 5 * 2) + cal(6 / 2 + 8) + 5」
  • 遇到当前数字的下一个运算符时,才会计算当前数字的结果,因此:
  • 遇到右括号需要进行计算,否则如 5 * 2 的结果将会被抛弃
  • 遇到字符串结束需要计算,否则如 + 5 的结果将会被抛弃
class Solution {
public:
	// 当前字符为以下 5 个字符时需要进行计算
    set<char> se = {'+', '-', '*', '/',')'};
    int calculate(string s) {
        int i = 0;
        return parseExptr(s, i);
    }
    int parseExptr(string& s, int& i) {
        char op = '+';
        int num = 0;
        int left = 0, right = 0;
        while(i < s.size()) {
            char c = s[i];
            if (isdigit(c)) {
                num = num * 10 + (c- '0');
            }
            // + 2*(5+5*2)+(6/2+8) + 5
            if (c == '(') {
            	// 向下递归,向后移动一个字符,防止重复遇到左括号
                i++;
                num = parseExptr(s, i);
                // 返回了括号内的运算结果 15
                // + 2 * 15 +····
                // 此时 c 为 '(',不会执行计算,继续 i++,由于 i 是引用传递,此时 i 已经指向 右括号,i++ 后指向右括号后面字符
            }
            // 遇到了四种运算符、遇到了右括号、到达结尾位置,进行计算
            if (se.count(c) || i == s.size() - 1) {
                switch(op) {
                    case '+' : left += right; right = num; break;
                    case '-' : left += right; right = -num; break;
                    case '*' : right *= num; break;
                    case '/' : right /= num; break;
                    default: break;
                }
                // 当 c 为 ‘)’ 时,op 为 ‘)’,但此时会向上返回,不会影响结果
                op = c;
                num = 0;
            }
            if (c == ')') break; // 结束循环,返回结果
            i++;
        }
        return left + right;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值