计算规则
概念
前缀(波兰表达式):前缀表达式的运算符位于操作数之前 如(3+4)*5-6 ==> - * + 3 4 5 6
计算时从右向左扫描,遇到数将其压入堆栈,遇到符号从栈内弹出两个数进行计算,将结果再次入栈,扫描结
束,栈内的值即为结果,减和除先弹出的数在前
中缀表达式:我们日常使用的形式(计算机不易识别)
后缀(逆波兰表达式):运算符位于操作数之后 如 (3+4)*5-6 ==> 3 4 + 5 * 6 -
计算时从左到右扫描,遇到数将其压入堆栈,遇到符号从栈内弹出两个数进行计算,将结果再次入栈,扫描结
束,栈内的值即为结果,减和除后弹出的数在前
中缀转后缀算法:
1.初始化两个栈num和oper
2.对中缀字符串依次扫描
3.遇到数字直接压入num栈
4.遇到括号
** 如果是"(",直接压入oper栈
** 如果是")",依次弹出oper栈的栈顶数据,直到遇到"(",将此括号弹出
5.遇到运算符
** 如果num栈空或者栈内为"("或者优先级比栈顶高,直接将其压入oper栈
** 若运算符比栈顶低或相等,将oper栈顶弹出并压入nun栈,再次从第5步进行判断
6.扫描完成后,将oper栈依次弹出并压入到num栈
7.num栈内元素依次弹出的逆序表达式即为此中缀表达式的后缀表达式
计算器
只考虑四则运算且不考虑小数情况
public class Poland {
public static void main(String[] args) {
String str = "(3+4)*5-6";
List<String> list = toInfixExpressionList(str);
System.out.println(calculate(toSuffixExpression(list)));
}
public static List<String> toSuffixExpression(List<String> list) {
Stack<String> operStack = new Stack<>();
List<String> num = new ArrayList<>();
for (String item : list) {
if (item.matches("\\d+")) {
num.add(item);
} else if ("(".equals(item)) {
operStack.push(item);
} else if (")".equals(item)) {
while (!"(".equals(operStack.peek())) {
num.add(operStack.pop());
}
operStack.pop();
} else {
while (operStack.size() != 0 && !"(".equals(operStack.peek()) && priority(item.charAt(0)) <= priority(operStack.peek().charAt(0))) {
num.add(operStack.pop());
}
operStack.push(item);
}
}
while (operStack.size() != 0) {
num.add(operStack.pop());
}
return num;
}
public static List<String> toInfixExpressionList(String str) {
int index = 0;
String s;
char c;
List<String> list = new ArrayList<>();
while (index < str.length()) {
if ((c = str.charAt(index)) < '0' || (c = str.charAt(index)) > '9') {
list.add(c + "");
index++;
} else {
s = "";
while (index < str.length() && str.charAt(index) >= '0' && (c = str.charAt(index)) <= '9') {
s += c;
index++;
}
list.add(s);
}
}
return list;
}
public static int priority(int oper) {
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '-' || oper == '+') {
return 0;
} else {
return -1;
}
}
public static List<String> getStrList(String str) {
List<String> list = new ArrayList<>();
String[] strings = str.split(" ");
Collections.addAll(list, strings);
return list;
}
public static int calculate(List<String> list) {
Stack<String> stack = new Stack<>();
for (String str : list) {
if (str.matches("\\d+")) {
stack.push(str);
} else {
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
int res;
if ("+".equals(str)) {
res = num1 + num2;
} else if ("-".equals(str)) {
res = num2 - num1;
} else if ("*".equals(str)) {
res = num1 * num2;
} else if ("/".equals(str)) {
res = num2 / num1;
} else {
throw new RuntimeException("符号有误");
}
stack.push(res + "");
}
}
return Integer.parseInt(stack.pop());
}
}