美文网首页
中缀表达式java实现

中缀表达式java实现

作者: 雨夜微凉886 | 来源:发表于2019-10-14 19:05 被阅读0次

中缀表达式的求解需要两个栈来存储,且设置为泛型,一个栈存操作数,一个栈存操作符,需要输入一个表达式字符串并将其转为字符串数组以提取有效字符。

节点类

public class Node<T> {

Node next;
T data;

public Node() {
    super();
    
}

public Node(T data) {
    super();
    this.data = data;
}

public Node(T data, Node next) {
    super();
    this.next = next;
    this.data = data;
}



public Node getNext() {
    return next;
}

public void setNext(Node next) {
    this.next = next;
}

public T getData() {
    return data;
}

public void setData(T data) {
    this.data = data;
}

}

栈类

public class LinkStack<T> {

private Node<T> top;

public LinkStack() {
    super();
    // TODO Auto-generated constructor stub
}

public LinkStack(Node top) {
    super();
    this.top = top;
}

public T getTop() {
    return top.data;
}

public void setTop(T data) {
    this.top.data= data;
}

public Node push(T data ) {
    Node top = this.top;
    Node newTop = new Node(data,top);
    this.top=newTop;
    return top;
}
public boolean isEmpty() {
    
    return this.top==null?true:false;
}

public T pop() throws Exception {
    if(this.isEmpty()) {
        throw new Exception(" 栈为空,不能弹出");
    }
    Node popNode = this.top;
    this.top=popNode.next;
    return (T) popNode.data;
}

public boolean makeEmpty() {
    this.top=null;
    return false;
}
public T peek() throws Exception {
    if(this.isEmpty()) {
        throw new Exception("栈为空,不能得到顶部元素");
    }
    return this.top.data; 
}

}

求解类

import java.util.Scanner;
//支持小数点和负数
//1+2(123+6)/2-3
//5+4(6(4-2)-2+63)/2+4(1+2)
//(-1+2)
//5+4(6(4-2)-2+63)/2+4(1+2)+(-7+8)+(-1)
public class Solution {
public static void main(String[] args) throws Exception {
Scanner input = new Scanner(System.in);
//操作数栈
LinkStack<Integer> OPND = new LinkStack<Integer>();
//操作符栈
LinkStack<Character> OPTR = new LinkStack<Character>();

    System.out.println("请输入一个中缀表达式:");
    String[] expression = formatInput(input.nextLine());
    // 首先,遍历expression数组,同时以下列原则进行操作,然后,对栈内的剩余数字进行运算,直到操作符栈为空
    for (String string : expression) {
        
        if(string.length()==0) {    // 因为格式化的时候是在非数字符号前后加空格,所以会存在分割出来是空的情况
            continue;
        }
        //如果是操作符则判断并计算,包括会计算左括号里面操作符优先级大的表达式
        else if(string.equals("+") || string.equals("-") || string.equals("*")|| string.equals("/")) {// 遇到运算符,将栈内优先级大于等于自己的符号拿出来参与计算
            //这里要注意
            while(!OPTR.isEmpty()&&priorityIsBiggerorSame(OPTR.peek()+"",string)) {// 循环直到栈空或者在栈中取到优先级相等或较小的符号
                computer(OPND,OPTR);
            }

            OPTR.push(string.charAt(0));//入栈
        }
        else if(string.equals("(")) {//遇到左括号入栈
            OPTR.push('(');
        }
        else if(string.equals(")")) {//遇到右括号,计算括号内的全部表达式,循环直到遇到左括号
            if(OPND.isEmpty()) {
                throw new Exception("表达式无意义");
            }
            while(OPTR.peek() != '(') {
                computer(OPND,OPTR);//实际上该过程一直计算优先级相等的表达式
            }
            OPTR.pop();
        }
        else {  //操作数入栈
            OPND.push(Integer.parseInt(string));
        }
        
    }
    
    while(!OPTR.isEmpty()) {//将所有符号出栈参与运算
        computer(OPND,OPTR);
    }
    
    System.out.println(OPND.peek());//输出结果

}

// 格式化中缀表达式输入,即在符号前后添加空格,便于后面的分隔操作
public static String[] formatInput(String s) {
    String temp = "";
    /*
     * 提取出表达式中有效的字符(非空格),然后在字符后面统一添上一个空格,方便后面使用静态方法String.split()来 
     * 例如:1 *(2+ 3) /4     ----->     1 * ( 2 + 3 ) / 4 
     * 你也可以直接使用List类来存储提取的有效字符 总之最后的目的就是返回一个数组,其中存储的是有效字符
     * 每一个有效数字由操作数分隔开
     */
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c == '+' || c == '-' || c == '*' || c == '/'||c=='('||c==')') {
            
            //如出现-1+3或(-3+4)这种
            if(i>0&& s.charAt(i-1)=='('||i==0) {
                temp += c;
            }
            
            else {
            temp += " " + c + " ";
            }
        }
        else
            temp += c;// 数字不用加空格
    }
    String[] expression=temp.split(" ");
   // System.out.println(expression);
    return expression;// 分割
}

// 优先级判断,a是否大于b
public static boolean priorityIsBiggerorSame(String a, String b) {
    String s = "+- */";
    return (s.indexOf(a) - s.indexOf(b)>= 2)||(s.indexOf(a) - s.indexOf(b)==1);
}

public static void computer(LinkStack<Integer> OPND,LinkStack<Character> OPTR) throws Exception {
    int  v1 = OPND.pop();
    int v2=OPND.pop();
    Character op=OPTR.pop();
    switch (op) {
    case '+':
        OPND.push(v2 + v1);
        break;
    case '-':
        OPND.push(v2 - v1);
        break;
    case '*':
        OPND.push(v2 * v1);
        break;
    case '/':
        OPND.push(v2 / v1);
        break;
    }
    
}

}

相关文章

网友评论

      本文标题:中缀表达式java实现

      本文链接:https://www.haomeiwen.com/subject/dvqdmctx.html