前缀表达式、中缀表达式、后缀表达式都是四则运算的表达方式,用以四则运算表达式求值
,即数学表达式的求职express
中缀表达式就是常见的运算表达式,如(3+4)×5-6code
前缀表达式又称波兰式,前缀表达式的运算符位于操做数以前字符串
好比:- × + 3 4 5 6get
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们作相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果数学
- 从右至左扫描,将六、五、四、3压入堆栈
- 遇到+运算符,所以弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式作比较),计算出3+4的值,得7,再将7入栈
- 接下来是×运算符,所以弹出7和5,计算出7×5=35,将35入栈
- 最后是-运算符,计算出35-6的值,即29,由此得出最终结果
转换步骤以下:it
例如:1+((2+3)×4)-5具体过程,以下表io
扫描到的元素 | S2(栈底->栈顶) | S1 (栈底->栈顶) | 说明 |
---|---|---|---|
5 | 5 | 空 | 数字,直接入栈 |
- | 5 | - | s1为空,运算符直接入栈 |
) | 5 | -) | 右括号直接入栈 |
4 | 5 4 | -) | 数字直接入栈 |
x | 5 4 | -)x | s1栈顶是右括号,直接入栈 |
) | 5 4 | -)x) | 右括号直接入栈 |
3 | 5 4 3 | -)x) | 数字 |
+ | 5 4 3 | -)x)+ | s1栈顶是右括号,直接入栈 |
2 | 5 4 3 2 | -)x)+ | 数字 |
( | 5 4 3 2 + | -)x | 左括号,弹出运算符直至遇到右括号 |
( | 5 4 3 2 + x | - | 同上 |
+ | 5 4 3 2 + x | -+ | 优先级与-相同,入栈 |
1 | 5 4 3 2 + x 1 | -+ | 数字 |
到达最左端 | 5 4 3 2 + x 1 + - | 空 | s1剩余运算符 |
结果是:- + 1 × + 2 3 4 5table
后缀表达式又称逆波兰表达式,与前缀表达式类似,只是运算符位于操做数以后class
好比:3 4 + 5 × 6 -求职
与前缀表达式相似,只是顺序是从左至右:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们作相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果
例如后缀表达式“3 4 + 5 × 6 -”:
与转换为前缀表达式类似,步骤以下:
例如,将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的过程以下:
扫描到的元素 | s2(栈底->栈顶) | s1 (栈底->栈顶) | 说明 |
---|---|---|---|
1 | 1 | 空 | 数字,直接入栈 |
+ | 1 | + | s1为空,运算符直接入栈 |
( | 1 | + ( | 左括号,直接入栈 |
( | 1 | + ( ( | 同上 |
2 | 1 2 | + ( ( | 数字 |
+ | 1 2 | + ( ( + | s1栈顶为左括号,运算符直接入栈 |
3 | 1 2 3 | + ( ( + | 数字 |
) | 1 2 3 + | + ( | 右括号,弹出运算符直至遇到左括号 |
× | 1 2 3 + | + ( × | s1栈顶为左括号,运算符直接入栈 |
4 | 1 2 3 + 4 | + ( × | 数字 |
) | 1 2 3 + 4 × | + | 右括号,弹出运算符直至遇到左括号 |
- | 1 2 3 + 4 × + | - | -与+优先级相同,所以弹出+,再压入- |
5 | 1 2 3 + 4 × + 5 | - | 数字 |
到达最右端 | 1 2 3 + 4 × + 5 - | 空 | s1中剩余的运算符 |
所以结果为“1 2 3 + 4 × + 5 -”
public class Operation { private static int ADDITION=1; private static int SUBTRACTION=1; private static int MULTIPLICATION=2; private static int DIVISION=2; public static int getValue(String operation){ int result; switch (operation){ case "+": result=ADDITION; break; case "-": result=SUBTRACTION; break; case "*": result=MULTIPLICATION; break; case "/": result=DIVISION; break; default: // System.out.println("不存在该运算符"); result=0; } return result; } } public class PolishNotation { public static void main(String[] args) { Scanner sc=new Scanner(System.in); System.out.println("请输入运算表达式:"); String expressionStr=sc.nextLine(); // System.out.println(expressionStr); List<String> zx= toInfixExpression(expressionStr); List<String> rpn=parseSuffixExpression(zx); String rpnStr=""; for(String str:rpn){ rpnStr+=str; } System.out.println(rpnStr); System.out.println("计算结果:"+ calculate(rpn)); } /** * 把字符串转换成中序表达式 * @param s * @return */ public static List<String> toInfixExpression(String s) { List<String> ls = new ArrayList<String>();//存储中序表达式 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; } /** * 转换成逆波兰表达式 * @param ls * @return */ public static List<String> parseSuffixExpression(List<String> ls) { Stack<String> s1=new Stack<String>(); Stack<String> s2=new Stack<String>(); List<String> lss = new ArrayList<String>(); for (String ss : ls) { if (ss.matches("\\d+")) { lss.add(ss); } else if (ss.equals("(")) { s1.push(ss); } else if (ss.equals(")")) { while (!s1.peek().equals("(")) { lss.add(s1.pop()); } s1.pop(); } else { while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(ss)) { lss.add(s1.pop()); } s1.push(ss); } } while (s1.size() != 0) { lss.add(s1.pop()); } return lss; } /** * 经过逆波兰表达式计算结果 * @param ls * @return */ public static int calculate(List<String> ls) { Stack<String> s=new Stack<String>(); for (String str : ls) { if (str.matches("\\d+")) { s.push(str); } else { int b = Integer.parseInt(s.pop()); int a = Integer.parseInt(s.pop()); int result=0; if (str.equals("+")) { result = a + b; } else if (str.equals("-")) { result = a - b; } else if (str.equals("*")) { result = a * b; } else if (str.equals("\\")) { result = a / b; } s.push("" + result); } } System.out.println(s.peek()); return Integer.parseInt(s.pop()); } }