栈——表达式求值

通过栈来实现表达式的计算

主要问题在于:运算符的优先级关系处理

算法思想:

  1.建立并初始化 运算符栈OPTR栈 和 数值OPND栈,将表达式起始符"#"压入OPTR栈;

  2.按序获取表达式数组中每个字符串str(假定表达式是合法有效的):

    ->如果str表示数值:

      直接压入OPND栈,进入下一次for循环;

    ->如果str表示运算符:    

      取出OPTR的栈顶运算符 top,比较str和top之间的优先级关系:

      ->如果优先级关系相等:

        ->如果top和str的均为"#":

          整个表达式求值完毕 return OPND栈顶元素;

        ->如果栈顶元素是左括号"(",读入str为")":

          那么将OPTR栈顶弹出,进入下一次for循环;

      ->如果top优先级大于str:

        弹出OPND栈顶元素2个(b, a),弹出OPTR栈顶元素(top),然后计算:result = a top b;

        将result压入OPND栈,将当前数组的遍历下标值减一,进入下一次for循环;

      ->如果top优先级小于str:

        将str压入OPTR栈;      

运算符之间的优先级比较:

  top\str + - * / #
  + > > < < < > >
  - > > < < < > >
  * > > > > < > >
  / > > > > < > >
  ( < < < < < =  
  ) > > > >   > >
  3 < < < < <   =

 

Java代码如下:

  1 package learn.normalcode;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Collections;
  5 import java.util.Stack;
  6 
  7 /**
  8  * 基础表达式求值(使用2个栈完成)
  9  */
 10 public class BlankZ {
 11 
 12     private static int[][] relationTable = new int[50][50];
 13     static {
 14         int add = '+' - '!';
 15         int reduce = '-' - '!';
 16         int mu = '*' - '!';
 17         int div = '/' - '!';
 18         int left_K = '(' - '!';
 19         int right_K = ')' - '!';
 20         int jin = '#' - '!';
 21         int[] symbol = {add, reduce, mu, div, left_K, right_K, jin};
 22         for (int i = 0; i < 7; ++i) {
 23 //            System.out.println(symbol[i]);
 24         }
 25         for (int i = 0; i < 7; ++i) {
 26             relationTable[add][symbol[i]] = 1;
 27             relationTable[reduce][symbol[i]] = 1;
 28             relationTable[mu][symbol[i]] = 1;
 29             relationTable[div][symbol[i]] = 1;
 30             relationTable[left_K][symbol[i]] = -1;
 31             relationTable[right_K][symbol[i]] = 1;
 32             relationTable[jin][symbol[i]] = -1;
 33         }
 34         relationTable[add][mu] = relationTable[add][div] = relationTable[add][left_K] = -1;
 35         relationTable[reduce][mu] = relationTable[reduce][div] = relationTable[reduce][left_K] = -1;
 36         relationTable[mu][left_K] = -1;
 37         relationTable[div][left_K] = -1;
 38         relationTable[left_K][right_K] = 0;
 39         relationTable[jin][jin] = 0;
 40     }
 41     public static boolean strIsSymbol(String str) {
 42         char c = str.charAt(0);
 43         return str.length() == 1 && !(c >= '0' && c <= '9');
 44     }
 45     public static int compare(String topSymbol, String str) {
 46         return relationTable[topSymbol.charAt(0) - '!'][str.charAt(0) - '!'];
 47     }
 48     public static String compute(int num2, int num1, char c) {
 49         int result = 0;
 50         switch (c) {
 51             case '+':
 52                 result = num1 + num2;
 53                 break;
 54             case '-':
 55                 result = num1 - num2;
 56                 break;
 57             case  '*':
 58                 result = num1 * num2;
 59                 break;
 60             case '/':
 61                 result = num1 / num2;
 62                 break;
 63         }
 64         return String.valueOf(result);
 65     }
 66     public static void main(String[] args) {
 67         Stack<String> numbers = new Stack<>();
 68         Stack<String> operators = new Stack<>();
 69 
 70         operators.add("#");
 71 
 72         String[] arr = {"3", "-", "2", "*", "(", "5", "+", "(", "2", "+", "0", ")", ")", "*", "3", "/", "2", "#"};
 73         ArrayList<String> sentence = new ArrayList<>(11);
 74         Collections.addAll(sentence, arr);
 75 
 76         for (int i = 0; i < sentence.size(); ++i) {
 77             String str = sentence.get(i);
 78 
 79             if (strIsSymbol(str)) {
 80                 String topElement = operators.peek();
 81                 int compareResult = compare(topElement, str);
 82                 if (compareResult == 0) {
 83                     //判断是否是结束符号 #
 84                     if (str.equals("#")) {
 85                         operators.pop();
 86                         System.out.println(numbers.pop());
 87                         return;
 88                     } else {
 89                         operators.pop();
 90                     }
 91                 } else if (compareResult > 0) {
 92                     //取出topElement,以及numbers中的2个顶部元素,进行计算
 93                     operators.pop();
 94                     numbers.add(compute(Integer.valueOf(numbers.pop()), Integer.valueOf(numbers.pop()), topElement.charAt(0)));
 95                     i--;
 96                 } else {
 97                     operators.add(str);
 98                 }
 99             } else {
100                 numbers.add(str);
101             }
102         }
103     }
104 }

猜你喜欢

转载自www.cnblogs.com/orzt/p/11503134.html