计算机问题解决
计算器也是非常常见的问题,我们看一个中等问题。LeetCode227.给你一个字符串表达式 s,请你实现一个基本计算器来计算并返回它的值。整数除法仅保留整数部分。
先说一下解题思路:
- 创建一个栈 stack 用于暂存中间结果。 初始化一个字符变量 preSign,用于存储当前数字之前的符号,默认为 +。
- 初始化一个整型变量 num,用于存储当前数字的值。 获取字符串 s 的长度,并开始遍历字符串的每个字符。
- 如果字符是数字字符,则将其转换为数字值并累加到 num 上。 如果字符不是数字字符且不是空格,或者已经遍历到字符串的最后一个字符:
- 根据preSign 的值,对 num 进行不同的操作: 如果 preSign 是 +,则将 num 推入栈 stack 中。
- 如果preSign 是 -,则将 num 的负值推入栈 stack 中。 如果 preSign 是 *,则将栈顶元素弹出,与 num相乘,再将结果推入栈 stack 中。
- 如果 preSign 是 /,则将栈顶元素弹出,与 num 相除,再将结果推入栈 stack中。 更新 preSign 为当前字符。 将 num 重置为0,以便下一次记录新的数字。
- 遍历完整个字符串后,栈 stack中存储的就是各个子表达式的结果。将栈中的所有元素相加(因为加法运算的优先级最低),得到最终的结果。
- 返回最终结果。
代码如下(示例):
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。
这种转换方式的好处是,它可以将多个数字字符按照正确的顺序转换为对应的整数,并且可以处理多位数的情况。