中綴表達(dá)式j(luò)ava實(shí)現(xiàn)

中綴表達(dá)式的求解需要兩個(gè)棧來存儲,且設(shè)置為泛型,一個(gè)棧存操作數(shù),一個(gè)棧存操作符,需要輸入一個(gè)表達(dá)式字符串并將其轉(zhuǎn)為字符串?dāng)?shù)組以提取有效字符。

節(jié)點(diǎn)類

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;
//支持小數(shù)點(diǎn)和負(fù)數(shù)
//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);
//操作數(shù)棧
LinkStack<Integer> OPND = new LinkStack<Integer>();
//操作符棧
LinkStack<Character> OPTR = new LinkStack<Character>();

    System.out.println("請輸入一個(gè)中綴表達(dá)式:");
    String[] expression = formatInput(input.nextLine());
    // 首先,遍歷expression數(shù)組,同時(shí)以下列原則進(jìn)行操作,然后,對棧內(nèi)的剩余數(shù)字進(jìn)行運(yùn)算,直到操作符棧為空
    for (String string : expression) {
        
        if(string.length()==0) {    // 因?yàn)楦袷交臅r(shí)候是在非數(shù)字符號前后加空格,所以會存在分割出來是空的情況
            continue;
        }
        //如果是操作符則判斷并計(jì)算,包括會計(jì)算左括號里面操作符優(yōu)先級大的表達(dá)式
        else if(string.equals("+") || string.equals("-") || string.equals("*")|| string.equals("/")) {// 遇到運(yùn)算符,將棧內(nèi)優(yōu)先級大于等于自己的符號拿出來參與計(jì)算
            //這里要注意
            while(!OPTR.isEmpty()&&priorityIsBiggerorSame(OPTR.peek()+"",string)) {// 循環(huán)直到??栈蛘咴跅V腥〉絻?yōu)先級相等或較小的符號
                computer(OPND,OPTR);
            }

            OPTR.push(string.charAt(0));//入棧
        }
        else if(string.equals("(")) {//遇到左括號入棧
            OPTR.push('(');
        }
        else if(string.equals(")")) {//遇到右括號,計(jì)算括號內(nèi)的全部表達(dá)式,循環(huán)直到遇到左括號
            if(OPND.isEmpty()) {
                throw new Exception("表達(dá)式無意義");
            }
            while(OPTR.peek() != '(') {
                computer(OPND,OPTR);//實(shí)際上該過程一直計(jì)算優(yōu)先級相等的表達(dá)式
            }
            OPTR.pop();
        }
        else {  //操作數(shù)入棧
            OPND.push(Integer.parseInt(string));
        }
        
    }
    
    while(!OPTR.isEmpty()) {//將所有符號出棧參與運(yùn)算
        computer(OPND,OPTR);
    }
    
    System.out.println(OPND.peek());//輸出結(jié)果

}

// 格式化中綴表達(dá)式輸入,即在符號前后添加空格,便于后面的分隔操作
public static String[] formatInput(String s) {
    String temp = "";
    /*
     * 提取出表達(dá)式中有效的字符(非空格),然后在字符后面統(tǒng)一添上一個(gè)空格,方便后面使用靜態(tài)方法String.split()來 
     * 例如:1 *(2+ 3) /4     ----->     1 * ( 2 + 3 ) / 4 
     * 你也可以直接使用List類來存儲提取的有效字符 總之最后的目的就是返回一個(gè)數(shù)組,其中存儲的是有效字符
     * 每一個(gè)有效數(shù)字由操作數(shù)分隔開
     */
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c == '+' || c == '-' || c == '*' || c == '/'||c=='('||c==')') {
            
            //如出現(xiàn)-1+3或(-3+4)這種
            if(i>0&& s.charAt(i-1)=='('||i==0) {
                temp += c;
            }
            
            else {
            temp += " " + c + " ";
            }
        }
        else
            temp += c;// 數(shù)字不用加空格
    }
    String[] expression=temp.split(" ");
   // System.out.println(expression);
    return expression;// 分割
}

// 優(yōu)先級判斷,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;
    }
    
}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java經(jīng)典問題算法大全 /*【程序1】 題目:古典問題:有一對兔子,從出生后第3個(gè)月起每個(gè)月都生一對兔子,小兔子...
    趙宇_阿特奇閱讀 2,083評論 0 2
  • 50道經(jīng)典Java編程練習(xí)題,將數(shù)學(xué)思維運(yùn)用到編程中來。抱歉哈找不到文章的原貼了,有冒犯的麻煩知會聲哈~ 1.指數(shù)...
    OSET我要編程閱讀 7,290評論 0 9
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡單原理和應(yīng)用。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 5,235評論 1 114
  • 多態(tài) 任何域的訪問操作都將有編譯器解析,如果某個(gè)方法是靜態(tài)的,它的行為就不具有多態(tài)性 java默認(rèn)對象的銷毀順序與...
    yueyue_projects閱讀 1,094評論 0 1
  • 一、基礎(chǔ)知識:1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,573評論 0 4

友情鏈接更多精彩內(nèi)容