JAVA-棧實現中序運算式求值

來源:互聯網
上載者:User

標籤:system   用兩個棧   void   pop   首碼運算式   電腦   row   equals   blog   

中序運算式對我們而言是很直觀的(我們平時接觸的就是這個),但電腦處理起來比較麻煩(括弧、優先順序之類的),前序和後序運算式中沒有括弧,而且在計算中只需單向掃描,不需要考慮運算子的優先順序。如2*3/(2-1)+3*(4-1)

前序運算式就是首碼運算式,不含括弧的算術運算式,而且它是將運算子寫在前面,運算元寫在後面的運算式,例如:+/*23-21*3-4,也稱為“波蘭式”。

後序運算式與前序運算式掃描方式正好相反,例如:23*21-/341-*+。

 

用兩個棧實現中序運算式求值,運算式中只支援int( 但是計算的結果可能是float)

InfixExpr expr = new InfixExpr("2+3*4+5");

Assert.assertEquals(19, expr.evaluate(), 0.001f);

下面展示了在棧中具體的操作過程

下面是具體的實現代碼:

public class InfixExpr {    String expr = null;    public InfixExpr(String expr) {    this.expr = expr;    }    public float evaluate() {    char[] ch = expr.toCharArray();    MyStack stackOfTocken = new MyStack();    MyStack stackOfNumber = new MyStack();    for (int i = 0; i < ch.length; i++) {        if (Character.isDigit(ch[i])) {        int tmp = Integer.parseInt("" + ch[i]);        while (i < ch.length - 1 && Character.isDigit(ch[++i])) {            tmp = tmp * 10 + Integer.parseInt("" + ch[i]);        }        System.out.println(tmp);        stackOfNumber.push(tmp);        }        if (ch[i] == ‘+‘ || ch[i] == ‘-‘ || ch[i] == ‘*‘ || ch[i] == ‘/‘) {        stackOfTocken.push(ch[i]);        }        if (!(stackOfTocken.isEmpty()) && (char) stackOfTocken.peek() == ‘*‘) {        int tmp = Integer.parseInt("" + ch[++i]);        while (i < ch.length - 1 && Character.isDigit(ch[++i])) {            tmp = tmp * 10 + Integer.parseInt("" + ch[i]);        }        if (i != ch.length - 1) {            i--;        }        stackOfNumber.push(tmp);        int tmp1 = Integer.parseInt("" + stackOfNumber.pop());        int tmp2 = Integer.parseInt("" + stackOfNumber.pop());        stackOfNumber.push(tmp1 * tmp2);        stackOfTocken.pop();        }        if (!(stackOfTocken.isEmpty()) && (char) stackOfTocken.peek() == ‘/‘) {        int tmp = Integer.parseInt("" + ch[++i]);        while (i < ch.length - 1 && Character.isDigit(ch[++i])) {            tmp = tmp * 10 + Integer.parseInt("" + ch[i]);        }        if (i != ch.length - 1) {            i--;        }        stackOfNumber.push(tmp);        int tmp1 = Integer.parseInt("" + stackOfNumber.pop());        int tmp2 = Integer.parseInt("" + stackOfNumber.pop());        stackOfNumber.push(tmp2 / tmp1);        stackOfTocken.pop();        }    }    // 將棧中的數字和運演算法逆置,便於計算    reverse(stackOfNumber);    reverse(stackOfTocken);    while (!(stackOfTocken.isEmpty())) {        if ((char) stackOfTocken.peek() == ‘+‘) {        int tmp1 = Integer.parseInt("" + stackOfNumber.pop());        int tmp2 = Integer.parseInt("" + stackOfNumber.pop());        stackOfNumber.push(tmp1 + tmp2);        }                if ((char) stackOfTocken.peek() == ‘-‘) {        int tmp1 = Integer.parseInt("" + stackOfNumber.pop());        int tmp2 = Integer.parseInt("" + stackOfNumber.pop());        stackOfNumber.push(tmp1 - tmp2);        }        stackOfTocken.pop();    }    return Float.parseFloat("" + stackOfNumber.pop());    }    private void reverse(MyStack s) {    if (s.isEmpty()) {        return;    }    // 如果s裡面只有一個元素,就返回。具體實現是先pop出來一個,判斷剩下的是不是空棧。    Object tmp1 = s.pop();    reverse(s);    if (s.isEmpty()) {        s.push(tmp1);        return;    }    Object temp2 = s.pop();    reverse(s);    s.push(tmp1);    reverse(s);    s.push(temp2);    }}

 

 

 

以及測試案例:

public class InfixExprTest {    @Before    public void setUp() throws Exception {    }    @After    public void tearDown() throws Exception {    }    @Test    public void testEvaluate() {    // InfixExpr expr = new InfixExpr("300*20+12*5-20/4");    {        InfixExpr expr = new InfixExpr("2+3*4+5");        Assert.assertEquals(19.0, expr.evaluate(), 0.001f);    }    {        InfixExpr expr = new InfixExpr("3*20+12*5-40/2");        Assert.assertEquals(100.0, expr.evaluate(), 0.001f);    }    {        InfixExpr expr = new InfixExpr("3*20/2");        Assert.assertEquals(30, expr.evaluate(), 0.001f);    }    {        InfixExpr expr = new InfixExpr("20/2*3");        Assert.assertEquals(30, expr.evaluate(), 0.001f);    }    {        InfixExpr expr = new InfixExpr("10-30+50");        Assert.assertEquals(30, expr.evaluate(), 0.001f);    }    }}

 

JAVA-棧實現中序運算式求值

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.