题目
利用计算机计算算数表达式,只包含加减乘除四则运算,比如:34+13*9+44- 12/3
思路:通过两个栈来实现的。其中一个保存操作数的栈,另一个是保存运算符的栈。我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符, 就与运算符栈的栈顶元素进行比较。如果比运算符栈顶元素的优先级高,就将当前运算符压入栈;如果比运算符栈顶元素的优先 级低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取 2 个操作数,然后进行 计算,再把计算完的结果压入操作数栈,继续比较。
public class StackTest {
private int calcuteResult(int a,int b,char sym){
int result = 0;
switch (sym){
case '+':result = a + b;break;
case '-':result = a - b;break;
case '*':result = a * b;break;
case '/':result = a / b;break;
default:break;
}
return result;
}
/**
* 利用计算机计算算数表达式,只包含加减乘除四则运算,比如:34+13*9+44- 12/3
*
* 思路:通过两个栈来实现的。其中一个保存操作数的栈,另一个是保存运算符的栈。
* 我们从左向右遍历表达式,当遇到数字,我们就直接压入操作数栈;当遇到运算符,
* 就与运算符栈的栈顶元素进行比较。如果比运算符栈顶元素的优先级高,就将当前运算符压入栈;
* 如果比运算符栈顶元素的优先 级低或者相同,从运算符栈中取栈顶运算符,从操作数栈的栈顶取 2 个操作数,
* 然后进行 计算,再把计算完的结果压入操作数栈,继续比较。
*/
@Test
public void test1(){
Stack<Integer> data = new Stack<>();
Stack<Character> symbol = new Stack<>();
//String str = "34+13*9+44-12/3";
String str = "34+13*9+44-12/3*1";
int result = 0;//= calcuteResult(2,4,'*');
int dd = 0;
for(int i=0;i<str.length();i++){
if(str.charAt(i)>=48&&str.charAt(i)<=57){
//如果为数字,则利用 dd 中间变量计算值
dd = dd * 10 + str.charAt(i) - 48;
//表达式最后一位为数字,压入堆栈
if(i == str.length() -1){
data.push(dd);
dd = 0;
}
}else {
//如果为运算符,则将中间变量dd压入堆栈
data.push(dd);
dd = 0;
//如果运算符栈为空,则将运算符直接压入堆栈
if(symbol.size() == 0) {
symbol.push(str.charAt(i));
}else if((str.charAt(i) == '+' || str.charAt(i) == '-')
&&(symbol.peek() == '*' || symbol.peek() == '/')){
//如果当前的运算符 str.charAt(i) 优先级小于 symbol 栈顶,则取出
// 数据栈 data 的前两个数值,与栈顶运算符一起计算,并将计算结果压入数据栈
int b = data.pop();
int a = data.pop();
result = calcuteResult(a,b,symbol.pop());
data.push(result);
symbol.push(str.charAt(i));
}else {
//栈顶不为空,且当前的运算符的优先级也不小于栈顶运算符,则将当前运算符压入堆栈
symbol.push(str.charAt(i));
}
}
}
//对数据栈与运算符栈中剩余元素进行计算
while (symbol.size() > 0){
int b = data.pop();
int a = data.pop();
char sys = symbol.pop();
result = calcuteResult(a,b,sys);
data.push(result);
}
System.out.println("计算结果:"+result);
}
}
输出结果:
计算结果:191