• 栈——表达式求值


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

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

    算法思想:

      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栈;      

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

      topstr + - * / #
      + > > < < < > >
      - > > < < < > >
      * > > > > < > >
      / > > > > < > >
      ( < < < < < =  
      ) > > > >   > >
      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 }
  • 相关阅读:
    在Postman用post方式请求webapi
    C#控制台为输出内容设置背景色和字体颜色
    不卡界面,实现文件上传
    编译后的dll,xml,pdb分别是什么内容,各有什么用处?
    C#的dynamic解析xml
    Oracle中的正则表达式
    oracle中 connect by 递归查询用法
    oracle中 listagg() WITHIN GROUP () 行转列函数的使用
    oracle中dualde使用
    MYSQL基本命令
  • 原文地址:https://www.cnblogs.com/orzt/p/11503134.html
Copyright © 2020-2023  润新知