【算法通关村第四关——计算机问题解决】

计算机问题解决

计算器也是非常常见的问题,我们看一个中等问题。LeetCode227.给你一个字符串表达式 s,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。

先说一下解题思路:

  1. 创建一个栈 stack 用于暂存中间结果。 初始化一个字符变量 preSign,用于存储当前数字之前的符号,默认为 +。
  2. 初始化一个整型变量 num,用于存储当前数字的值。 获取字符串 s 的长度,并开始遍历字符串的每个字符。
  3. 如果字符是数字字符,则将其转换为数字值并累加到 num 上。 如果字符不是数字字符且不是空格,或者已经遍历到字符串的最后一个字符:
  4. 根据preSign 的值,对 num 进行不同的操作: 如果 preSign 是 +,则将 num 推入栈 stack 中。
  5. 如果preSign 是 -,则将 num 的负值推入栈 stack 中。 如果 preSign 是 *,则将栈顶元素弹出,与 num相乘,再将结果推入栈 stack 中。
  6. 如果 preSign 是 /,则将栈顶元素弹出,与 num 相除,再将结果推入栈 stack中。 更新 preSign 为当前字符。 将 num 重置为0,以便下一次记录新的数字。
  7. 遍历完整个字符串后,栈 stack中存储的就是各个子表达式的结果。将栈中的所有元素相加(因为加法运算的优先级最低),得到最终的结果。
  8. 返回最终结果。

代码如下(示例):

public  static int calculate(String s) {
        Deque<Integer> stack = new ArrayDeque<Integer>();
        char preSign = '+';
        int num = 0;
        int n = s.length();
        for (int i = 0; i < n; ++i) {
            if (Character.isDigit(s.charAt(i))) {
                //这里要得到对应的整型数字,需要减去'0'对应的ASCII码
                //如果要运算两位数或者三位数,使用该表达式可以得到对应的正确数字
                num = num * 10 + s.charAt(i) - '0';
                System.out.println((int)s.charAt(i));
            }
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1) {
                switch (preSign) {
                    case '+':
                        stack.push(num);
                        break;
                    case '-':
                        stack.push(-num);
                        break;
                    case '*':
                        stack.push(stack.pop() * num);
                        break;
                    default:
                        stack.push(stack.pop() / num);
                }
                preSign = s.charAt(i);
                num = 0;
            }
        }
        int ans = 0;
        while (!stack.isEmpty()) {
            ans += stack.pop();
        }
        return ans;
    }

重点

num = num * 10 + s.charAt(i) - ‘0’;
这行代码需要注意一下,
使用表达式 num = num * 10 + s.charAt(i) - ‘0’ 将字符转换为数字的好处是,它可以根据字符的数值大小来计算出正确的数字,而不仅仅是表示为ASCII码。

例如,当字符 ‘1’ 被转换为整数时,使用强制类型转换 int num = (int) s.charAt(i) 可以得到ASCII码 49,而使用表达式 num = num * 10 + s.charAt(i) - ‘0’ 可以得到数值 1。这是因为字符 ‘1’ 的ASCII码是 49,而字符 ‘0’ 的ASCII码是 48,通过将字符 ‘0’ 的ASCII码减去,我们可以得到实际的数值1。

当我们将字符 ‘1’ 和字符 ‘0’ 连接在一起得到字符串 ‘10’ 时,使用表达式 num = num * 10 + s.charAt(i) - ‘0’ 可以依次计算出数字1和数字0,并将它们合并为最终的数字10。

这种转换方式的好处是,它可以将多个数字字符按照正确的顺序转换为对应的整数,并且可以处理多位数的情况。

你可能感兴趣的:(算法,java,数据结构)