“携手创作,共同成长!开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情”
后缀表达式的计算机求值
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素和栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果
例如:(3+4)×5-6对应的后缀表达式就是34+5×6-,针对后缀表达式求值步骤如下
1)从左至右扫描,将3和4压入堆栈;
2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素〉,计算出3+4的值,得7,再将7入栈;
3)将5入栈;
4)接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;5)将6入栈;
6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果
完成一个简化的逆波兰计算器,实现如下任务:
1)输入一个逆波兰表达式(后缀表达式),使用栈(Stack),计算其结果
2)支持小括号和多位数整数,将计算器进行简化,只支持对整数的计算。
思路分析
1)先把3 4 + 5 × 6 - 中的数据放入一个ArrayList中去(因为一个个扫描太慢了)
2)将ArrayList传入一个方法,遍历数据配合栈进行计算
代码完成
public static List<String> getlistString(String suffixExpression){
String[] split = suffixExpression.split(" ");
List<String> list=new ArrayList<String>();
for (String ele:split){
list.add(ele);
}
return list;
}
//完成对逆波兰表达式的运算
public static int calcluate(List<String> ls){
//创建栈,只需要一个栈即可
Stack<String> stack = new Stack<>();
//遍历 ls
for (String item:ls) {
//使用正则表达式来判断数据是否是数字,若是数字就进行入栈
if(item.matches("\\d+")) {
stack.push(item);
} else { //若不是数,就是符号,进行出栈操作,
int num1=Integer.parseInt(stack.pop()); //将字符转换成数字
int num2=Integer.parseInt(stack.pop()); //将字符转换成数字
int res=0; //存入结果
if(item.equals("+")){
res=num2+num1; //要进行换序操作
} else if(item.equals("-")){
res=num2-num1; //要进行换序操作
} else if(item.equals("×")){
res=num2*num1; //要进行换序操作
} else if(item.equals("/")){
res=num2/num1; //要进行换序操作
} else {
throw new RuntimeException("运算符有错误");
}
//把res 入栈
stack.push(""+res); //通过前面加""可以直接将结果直接变成字符串类型的
}
}
//最后将留在stack的最后结果进行输出,最后别忘了将字符串类型的数字转成整型
return Integer.parseInt(stack.pop());
}
代码要点:
1. int num1=Integer.parseInt(stack.pop()); //将字符转换成数字
2. stack.push(""+res); //通过前面加""可以直接将结果直接变成字符串
3. 将字符串类型的数字转成整型Integer.parseInt(stack.pop());
测试代码:
public static void main(String[] args) {
//先定义一个逆波兰表达式
//(3+4)×5-6 所对应的 3 4 + 5 × 6 - =>29
//(30+4)×5-6 所对应的 3 4 + 5 × 6 - =>164
//为了方便表达式符号都要用空格隔开
String suffixExpression="30 4 + 5 × 6 - ";
List<String> list = getlistString(suffixExpression);
int res=calcluate(list);
System.out.println("计算的结果是="+res);
}