利用栈实现算术表达式求值(Java语言描述)

来源:互联网 发布:商标设计软件 编辑:程序博客网 时间:2024/05/17 22:16

算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识。声明:部分代码参考自茫茫大海的专栏。

链栈的实现:

  1. package 算数表达式求值;  
  2.   
  3. public class Stack<T> {  
  4.     //节点类  
  5.     public class Node{  
  6.         public T data;  
  7.         public Node next;  
  8.         public Node(){}  
  9.         public Node(T data,Node next){  
  10.             this.data = data;  
  11.             this.next = next;  
  12.         }  
  13.     }//Node  
  14.       
  15.     public Node top = new Node();  
  16.     public int size;  
  17.     public Node oldNode;  
  18.       
  19.     //入栈  
  20.     public void push(T element){  
  21.         top = new Node(element,top);  
  22.         size++;  
  23.     }  
  24.       
  25.     //出栈  
  26.     public T pop(){  
  27.         oldNode = top;  
  28.         top = top.next;  
  29.         //oldNode = null;  
  30.         size--;  
  31.         return oldNode.data;  
  32.     }  
  33.       
  34.     //返回栈顶对象的数据域,但不出栈  
  35.     public T peek(){  
  36.         return top.data;  
  37.     }  
  38.       
  39.     //栈长  
  40.     public int length(){  
  41.         return size;  
  42.     }  
  43.       
  44.     //判断栈是否为空  
  45.     public boolean isEmpty(){  
  46.         return size == 0;  
  47.     }  
  48.   
  49. }  

 表达式求值的实现:

  1. package 算数表达式求值;  
  2.   
  3. import java.util.Scanner;  
  4. //import java.util.Stack;  
  5. public class Expression {  
  6.       
  7.     //运算符之间的优先级,其顺序是+、-、*、/、(、),其中大于号表示优先级高  
  8.     //,小于号表示优先级低,等号表示优先级相同,感叹号表示没有优先关系  
  9.     public static final char[][] relation = {{'>','>','<','<','<','>','>'},  
  10.             {'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},  
  11.             {'>','>','>','>','<','>','>'},{'<','<','<','<','<','=','!'},  
  12.             {'>','>','>','>','!','>','>'},{'<','<','<','<','<','!','='}};  
  13.       
  14.     public static void main(String[] args) {  
  15.         Scanner input = new Scanner(System.in);  
  16.         while(true){  
  17.         try{  
  18.         System.out.println("请输入要计算的表达式:");  
  19.         String exp = input.next();  
  20.         System.out.println(calc(exp + "#"));  
  21.         }catch(ArithmeticException e1){  
  22.             System.out.println("表达式中的分母不能为0");  
  23.             e1.printStackTrace();  
  24.         }  
  25.         }  
  26.     }  
  27.     /** 
  28.      *  
  29.      * @param exp 要计算的表达式 
  30.      * @return 计算的结果 
  31.      */  
  32.     private static int calc(String exp) {  
  33.         //操作数栈  
  34.         Stack<Integer> num = new Stack<Integer>();  
  35.         //操作符栈  
  36.         Stack<Character> op = new Stack<Character>();  
  37.           
  38.         op.push('#');  
  39.         int i = 0;  
  40.         char ch = exp.charAt(i);  
  41.         boolean flag = false;//判断连续的几个字符是否是数字,若是,就处理成一个数字。这样就能处理多位数的运算了。  
  42.         while(ch != '#' || op.peek() != '#') {//peek()查看栈顶对象但不移除。  
  43.             if(ch >= '0' && ch <= '9') {  
  44.                 if(flag) {  
  45.                     int tmp = num.pop();  
  46.                     num.push(tmp * 10 + Integer.parseInt(ch + ""));  
  47.                 } else {  
  48.                     num.push(Integer.parseInt(ch + ""));  
  49.                 }  
  50.                 flag = true;  
  51.                 i++;  
  52.             } else {  
  53.                 flag = false;  
  54.                 switch(precede(op.peek(), ch)) {  
  55.                 case '<':  
  56.                     op.push(ch);  
  57.                     i++;  
  58.                     break;  
  59.                 case '=':  
  60.                     op.pop();  
  61.                     i++;  
  62.                     break;  
  63.                 case '>':  
  64.                     int num2 = num.pop();  
  65.                     int num1 = num.pop();  
  66.                     int result = operate(num1, op.pop(), num2);  
  67.                     num.push(result);  
  68.                     break;  
  69.                 case '!':  
  70.                     System.out.println("输入的表达式错误!");  
  71.                     return -1;  
  72.                 }  
  73.             }  
  74.             ch = exp.charAt(i);  
  75.         }  
  76.         return num.peek();  
  77.     }  
  78.     private static char precede(char peek, char ch) {  
  79.         return relation[getIndex(peek)][getIndex(ch)];  
  80.     }  
  81.       
  82.     /** 
  83.      *  
  84.      * @param ch 操作符 
  85.      * @return 操作符的索引,按照+、-、*、/、(、)的顺序 
  86.      */  
  87.     private static int getIndex(char ch) {  
  88.         int index = -1;  
  89.         switch(ch) {  
  90.         case '+':  
  91.             index = 0;  
  92.             break;  
  93.         case '-':  
  94.             index = 1;  
  95.             break;  
  96.         case '*':  
  97.             index = 2;  
  98.             break;  
  99.         case '/':  
  100.             index = 3;  
  101.             break;  
  102.         case '(':  
  103.             index = 4;  
  104.             break;  
  105.         case ')':  
  106.             index = 5;  
  107.             break;  
  108.         case '#':  
  109.             index = 6;  
  110.             break;  
  111.         }  
  112.         return index;  
  113.     }  
  114.       
  115.     /** 
  116.      *  
  117.      * @param num1  第一个运算数 
  118.      * @param ch 运算符 
  119.      * @param num2 第二个运算数 
  120.      * @return 运算结果 
  121.      */  
  122.     private static int operate(int num1, char ch, int num2) {  
  123.         int result = 0;  
  124.         switch(ch) {  
  125.         case '+':  
  126.             result = num1 + num2;  
  127.             break;  
  128.         case '-':  
  129.             result = num1 - num2;  
  130.             break;  
  131.         case '*':  
  132.             result = num1 * num2;  
  133.             break;  
  134.         case '/':  
  135.             result = num1 / num2;  
  136.             break;  
  137.         }  
  138.         return result;  
  139.     }  
  140. }  

异常处理有待完善,引用请指明出处。

0 0
原创粉丝点击