中缀表达式转后缀表达式
思路分析:
1) 初始化两个栈:运算符栈s1和储存中间结果的栈s2(s2实际可用ArrayList);
2) 从左至右扫描中缀表达式;
3) 遇到操作数时,将其压s2;
4) 遇到运算符时,比较其与s1栈顶运算符的优先级:
(1)如果 s1 为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(2)否则,若优先级比栈顶运算符的高,也将运算符压入 s1;
(3)否则,将 s1 栈顶的运算符弹出并压入到 s2 中,再次转到 4) - (1) 与 s1 中新的栈顶运算符相比较;
5) 遇到括号时:
(1) 如果是左括号“(”,则直接压入s1
(2) 如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
6) 重复步骤2)至5),直到表达式的最右边
7) 将s1中剩余的运算符依次弹出并压入s2
8) 依次弹出s2中的元素并输出,结果的逆序(若s2为ArrayList则直接输出)即为中缀表达式对应的后缀表达式
举例:
将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的过程如下,结果为 "1 2 3 + 4 × + 5 –"
代码实现:
1. class infixTosuffix { 2. 3. /** 4. * 将Sting数组转为ArrayList 5. * @param s 6. * @return 7. */ 8. public static List<String> toinfixExpList(String[] s) { 9. ArrayList<String> list = new ArrayList<>(); 10. for (String s1 : s) { 11. list.add(s1); 12. } 13. return list; 14. } 15. 16. /** 17. * 中缀表达式转为后缀表达式的具体实现 18. * @param infixExpList 19. * @return 20. */ 21. public static List<String> toSuffixExpr(List<String> infixExpList) { 22. Stack<String> s1 = new Stack<>();//符号栈 23. 24. //说明:因为 s2 这个栈,在整个转换过程中,没有 pop 操作,而且后面我们还需要逆序输出 25. //因此比较麻烦,这里我们就不用 Stack<String> 直接使用 List<String> s2 26. ArrayList<String> s2 = new ArrayList<>();//存储中间结果的ArrayList 27. 28. 29. for (String s : infixExpList) { 30. if (Polandnotation.isNumeric(s)) {//如果是一个数,加入 s2 31. s2.add(s); 32. } else if (s1.size() == 0 || s.equals("(")) { 33. s1.push(s); 34. } else if (s.equals(")")) {/*如果是右括号“)”,则依次弹出 s1 栈顶的运算符,并压入 s2, 35. 直到遇到左括号则结束,最后将这一对括号丢弃*/ 36. while (!s1.peek().equals("(")) { 37. s2.add(s1.pop()); 38. } 39. s1.pop(); //还要将 “(” 弹出 s1 栈, 消除一对小括号 40. } else { 41. /*当 item 的优先级小于等于 s1 栈顶运算符, 42. 将 s1 栈顶的运算符弹出并加入到 s2 中,再次转到(4.1) 与 s1 中新的栈顶运算符相比较*/ 43. 44. // bug:这种写法s1.peek()可能为“(”,getPriority会走default 45. // while (s1.size() != 0 && 46. // infixTosuffix.getPriority(s) <= infixTosuffix.getPriority(s1.peek())) { 47. // s2.add(s1.pop()); 48. // } 49. while (s1.size() != 0) { 50. int sPriority = infixTosuffix.getPriority(s); 51. if (s1.peek().equals("(")) { 52. break; 53. } 54. int topPriority = infixTosuffix.getPriority(s1.peek()); 55. if (sPriority <= topPriority) { 56. s2.add(s1.pop()); 57. } 58. } 59. s1.push(s);//还需要将 item 压入栈 60. } 61. } 62. 63. while (s1.size() != 0) {//将 s1 中剩余的运算符依次弹出并加入 s2 64. s2.add(s1.pop()); 65. } 66. 67. return s2; //注意因为是存放到 List, 因此按顺序输出就是对应的后缀表达式对应的 List 68. } 69. 70. /** 71. * 获取运算符的优先级 72. * @param s 73. * @return 74. */ 75. public static int getPriority(String s) { 76. switch (s) { 77. case "+": 78. return 1; 79. case "-": 80. return 1; 81. case "*": 82. return 2; 83. case "/": 84. return 2; 85. default: 86. throw new RuntimeException("getPriority(): ERROR!!!!!"); 87. } 88. } 89. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>