波兰表达式

代码实现

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Stack;
  4. /**
  5. * @author laoduan
  6. * @create 2020-04-17-16:42
  7. */
  8. public class PolandNotation {
  9. public static void main(String[] args) {
  10. // String suffixExpression = "30 4 + 5 * 6 -";
  11. // String suffixExpression = "4 5 * 8 - 60 + 8 2 / +";
  12. // List<String> rpnList = getListString(suffixExpression);
  13. // System.out.println("rpnList="+rpnList);
  14. //
  15. // int res = calulate(rpnList);
  16. // System.out.println("计算的结果是"+res);
  17. //
  18. //
  19. String expression = "1+((2+3)*4)-5";
  20. List<String>infixExpressionList = toinfixExpressionList(expression);
  21. System.out.println(infixExpressionList);
  22. List<String> parseSuffixExpressionList = parseSuffixExpressionList(infixExpressionList);
  23. System.out.println("后缀表达式对应的List"+parseSuffixExpressionList);
  24. System.out.printf("expression=%d",calulate(parseSuffixExpressionList));
  25. }
  26. //方法:将得到的中缀表达式对应的List=》后缀表达式对应的List
  27. public static List<String> parseSuffixExpressionList(List<String> ls){
  28. //定义两个栈
  29. Stack<String>s1 = new Stack<String>();//符号栈
  30. //s2在整个转换过程中没有pop操作
  31. //所以直接用List
  32. List<String> s2 = new ArrayList<String>();
  33. //遍历ls
  34. for(String item:ls){
  35. //如果是一个数,入s2
  36. if(item.matches("\\d+")){
  37. s2.add(item);
  38. }
  39. else if(item.equals("(")){
  40. s1.push(item);
  41. }
  42. else if(item.equals(")")){
  43. //如果是),就一直弹出,直到(
  44. while (!s1.peek().equals("(")){
  45. s2.add(s1.pop());
  46. }
  47. s1.pop();//将(弹出s1 消除()
  48. }else {
  49. //当item的优先级小于等于s1栈顶运算符,将s1栈顶的运算符弹出并加入s2
  50. while (s1.size()!=0&&Operation.getValue(s1.peek())>=Operation.getValue(item)){
  51. s2.add(s1.pop());
  52. }
  53. //将item压入栈中
  54. s1.push(item);
  55. }
  56. }
  57. while (s1.size()!=0){
  58. s2.add(s1.pop());
  59. }
  60. return s2;//因为是存放到list,因此正常输出就是逆波兰
  61. }
  62. //将中缀表达式转成list
  63. public static List<String> toinfixExpressionList(String s){
  64. List<String> ls = new ArrayList<String>();
  65. int i = 0;
  66. String str;
  67. char c;
  68. do{
  69. //如果是非数字,加入到ls
  70. if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){
  71. ls.add(""+c);
  72. i++;
  73. }else {//如果是个数,要考虑多位数
  74. str = "";//先置空
  75. while (i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=57){
  76. str+=c;
  77. i++;
  78. }
  79. ls.add(str);
  80. }
  81. }while (i<s.length());
  82. return ls;
  83. }
  84. public static List<String> getListString(String suffixExpression){
  85. String[] split = suffixExpression.split(" ");
  86. List<String> list = new ArrayList<String>();
  87. for(String ele:split){
  88. list.add(ele);
  89. }
  90. return list;
  91. }
  92. public static int calulate(List<String> ls){
  93. Stack<String> stack = new Stack<String>();
  94. for (String item:ls){
  95. if(item.matches("\\d+")){
  96. stack.push(item);
  97. }else
  98. {
  99. //不是数,pop出两个数,运算
  100. int num2 = Integer.parseInt(stack.pop());
  101. int num1 = Integer.parseInt(stack.pop());
  102. int res = 0;
  103. if(item.equals("+")){
  104. res=num1+num2;
  105. }else if(item.equals("-")){
  106. res = num1-num2;
  107. }else if(item.equals("*")){
  108. res = num1*num2;
  109. }else if(item.equals("/")){
  110. res = num1/num2;
  111. }else {
  112. throw new RuntimeException("运算符有误");
  113. }
  114. //把res入栈
  115. stack.push(""+res);
  116. }
  117. }
  118. //最后留在stack的就是结果
  119. return Integer.parseInt(stack.pop());
  120. }
  121. }
  122. //Operation 可以返回一个运算符对应的优先级
  123. class Operation{
  124. private static int ADD = 1;
  125. private static int SUB = 1;
  126. private static int MUL = 2;
  127. private static int DIV = 2;
  128. //写一个方法,返回对应的优先级数字
  129. public static int getValue(String operation){
  130. int result = 0;
  131. switch (operation){
  132. case "+":
  133. result = ADD;
  134. break;
  135. case "-":
  136. result = SUB;
  137. break;
  138. case "*":
  139. result = MUL;
  140. break;
  141. case "/":
  142. result = DIV;
  143. break;
  144. default:
  145. System.out.println("不存在该运算符");
  146. break;
  147. }
  148. return result;
  149. }
  150. }