算术表达式求值是栈的典型应用,自己写栈,实现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. }  

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