栈实现综合计算器(2)
优点:可以实现多位数的加减乘除的计算
缺点:中缀表达式的求值是我们人最熟悉的,但是对计算机来说却不好操作。
思路分析
- 当我们把表达式存储在一个字符串当中时候,每次用index去扫描,对于多位数,我们就可以看作是多个单个字符串的拼接。
- 因此,每次当我们利用index进行扫描读取数据的时候,还需要考虑index的下一位,如果是数据的话,就继续向下一位扫描,直到是操作符为止
- 然后将数据拼接后,可以利用包装类再将字符串转换成数据的形式,便于接下去的计算操作。
代码实现
其余部分的代码详细可见栈实现综合计算器(1),此处展示的是,在处理数据时候的代码的变化。同时,需要在主函数一开始定义一个String类型的变量,来保存和拼接多位数的数据。
String keepNum = "";//用于拼接多位数
// 1.首先,扫描表达式expression
while (true) {
// 依次得到每一个字符
ch = expression.substring(index, index + 1).charAt(0);
// 判断ch是数字还是操作符,然后做相应的操作
if (operStack.isOper(ch)) {
// 如果是操作符,两种情况:1.operStack内有操作符,判断优先级2.没有操作符,直接入栈
// 没有操作符,直接入栈
if (operStack.isEmpty()) {
operStack.pushNum(ch);
} else {
// 如果栈顶有操作符,两种思路:
// 1.如果优先级ch > 栈顶的,直接入栈
// 2.如果优先级ch < 栈顶的,先把栈顶的取出来,并且从数据栈中取数做运算,然后分别把结果和ch再入栈到对应的栈中
if (operStack.priority(ch) <= operStack.priority(operStack.peak())) {
// 1.取出数据和操作符
num1 = numStack.popNum();
num2 = numStack.popNum();
oper = operStack.popNum();
// 2.做运算
res = numStack.cal(num1, num2, oper);
// 3.对应的数据和操作符入栈
numStack.pushNum(res);
operStack.pushNum(ch);
} else {
operStack.pushNum(ch);
}
}
} else {
// 如果是数字。直接入栈——numStack
// numStack.pushNum(ch - 48);// 此时因为是字符的格式,在Ascii码表中,数字和对应的字符格式相差48
//处理多位数的思路:
//需要让index扫描时候往index+1的位置上再多扫描一次,如果是数就继续向下一位扫描,如果index+1位是操作符,才将这个数入栈
//keepNum用于数字的拼接
//处理多位数
keepNum += ch;
if(index == expression.length()-1){//此时,index已经是最后一位,直接入栈
numStack.pushNum(Integer.parseInt(keepNum));//包装类和字符串的转换
}else{
if(operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))){
numStack.pushNum(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
index++;
if(index >= expression.length()){
break;
}
}
后续
因为考虑到这种方法的不便,所以我们可以通过逆波兰表达式的方式来实现综合计算器的效果。
拓展
- 前缀表达式:前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前
- 如:(3+4)×5-6 对应的前缀表达式就是 - × + 3 4 5 6
- 计算方法:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 和 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果 - 中缀表达式:中缀表达式就是常见的运算表达式,如(3+4)×5-6
- 中缀表达式的求值是我们人最熟悉的,但是对计算机来说却不好操作(前面我们演示的综合计算器就能看的这个问题),因此,在计算结果时,往往会将中缀表达式转成其它表达式来操作(一般转成后缀表达式.) - 后缀表达式:后缀表达式又称逆波兰表达式,与前缀表达式相似,只是运算符位于操作数之后。
- 如:(3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 –
- 还有其他的逆波兰表达式,如: