逆波兰计算器
- 输入一个逆波兰表达式(后缀表达式),使用栈,计算器结果;
- 思路:(以:(3+4)5-6,为例子,转为逆波兰表达式为:3 4 + 5 * 6 - )
1.从左到右扫描,将3和4先压入栈里;
2.遇到+运算法,因此弹出4和3(4为栈顶元素,3为次顶元素),计算出3+4的值,得7,再将7入栈;
3.将5入栈;
4.遇到,将弹出5和7,计算的35入栈;
5.将6入栈;
6.遇到-,取出35和6计算出29得出结果。
代码
现将输入的表达式转为List
public static List<String> getListString(String suffixExpresion) {
String[] split = suffixExpresion.split(" ");
List<String> list = new ArrayList<>();
for (String ele : split) {
list.add(ele);
}
return list;
}
将得到的List进行计算
public static int calculate(List<String> ls) {
Stack<String> stack = new Stack<>();
for (String str : ls) {
//使用正则表达式
if (str.matches("\\d+")) {
stack.push(str);
} else {
//pop出两个数进行运算
int n2 = Integer.parseInt(stack.pop());
int n1 = Integer.parseInt(stack.pop());
int res = 0;
if (str.equals("+")) {
res = n1 + n2;
} else if (str.equals("-")) {
res = n1 - n2;
} else if (str.equals("*")) {
res = n1 * n2;
} else if (str.equals("/")) {
res = n1 / n2;
} else {
throw new RuntimeException("Wrong operator!");
}
stack.push("" + res);
}
}
return Integer.parseInt(stack.pop());
}
中缀表达式转换为后缀表达式
步骤如下
1.初始化1个栈和一个链表,栈储存运算法,链表储存中间结果;
2.从左到右扫描中缀表达式;
3.遇到操作数时,将其放入链表;
4.遇到运算符时,比较和栈顶的运算法的优先级:
- 1.如果栈为空或者栈顶运算符为左括号“()”,则直接将此运算符入栈;
- 2.否则,若优先级比栈顶的运算符高,也将运算符压入栈中;
- 3.否则,将栈顶的运算符弹出并添加到链表中,再次站到第4.1步的第一步与新的栈顶进行比较
5.遇到括号时: - 1.如果是左括号“(”,则直接压入s1;
- 2.如果是有括号“)”,则一次弹出栈顶的运算符添加到链表里面,知道遇到左括号为止,此时将这一对括号丢弃;
6.重复2到5的步骤,知道表达式的最右边;
7.将栈中剩余的运算符一次弹出加入链表;
8.所得到的链表即为对应的后缀表达式。
代码实现
计算运算符的优先级类
package com.company;
import java.nio.channels.MulticastChannel;
public class Operation {
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
public static int getValue(String operation){
int result = 0;
switch (operation){
case "+":
result=ADD;
break;
case "-":
result=SUB;
break;
case "*":
result=MUL;
break;
case "/":
result=DIV;
break;
default:
result=0;
break;
}
return result;
}
}
将中缀表达式转换为List
public static List<String> toInfixExpressionList(String s){
List<String> ls = new ArrayList<>();
int i = 0;
String str;
char c;
do{
if((c=s.charAt(i))<48||(c=s.charAt(i))>57){
ls.add(""+c);
i++;
}else {//如果是一个数,要考虑多位数的问题
str = "";
while(i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=57){
str += c;
i++;
}
ls.add(str);
}
}while(i<s.length());
return ls;
}
转换为后缀表达式
public static List<String> parseSuffixExpresionList(List<String> ls) {
Stack<String> stack = new Stack<>();//符号栈
List<String> list = new ArrayList<>();//存储中间结果
//遍历ls
for (String item : ls) {
if (item.matches("\\d+")) {//正则表达式
list.add(item);
}else if(item.equals("(")){
stack.push(item);
}else if(item.equals(")")){
while(!stack.peek().equals("(")){
list.add(stack.pop());
}
stack.pop();
}else {
while(stack.size()!=0&&Operation.getValue(stack.peek())>=Operation.getValue(item)){
list.add(stack.pop());
}
stack.push(item);
}
}
while(stack.size()!=0){
list.add(stack.pop());
}
return list;
}