JAVA-栈实现中序表达式求值

中序表达式对我们而言是很直观的(我们平时接触的就是这个),但计算机处理起来比较麻烦(括号、优先级之类的),前序和后序表达式中没有括号,而且在计算中只需单向扫描,不需要考虑运算符的优先级。如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);
    }

    }

}
时间: 2024-12-19 12:34:48

JAVA-栈实现中序表达式求值的相关文章

栈的应用——四则表达式求值

栈的应用有很多,四则运算是一个比较常见的应用.对于四则运算,括号内的要先运算,而且还要先乘除后加减,又要涉及到负数和浮点数,看上去简简单单的式子,其实暗藏杀机. 常用的方法是利用后缀表达式(逆波兰)进行计算.主要分为两步: (1)将中缀表达式转化为后缀表达式(栈用来进出运算的符号): 从左到右遍历中缀表达式的每一个数字和符号,若是数字就输出,既成为后缀表达式的一部分,若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先加减),则栈顶元素依次出栈并输出,并将当前符号进栈,一

11、蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现

11.蛤蟆的数据结构笔记之十一栈的应用之表达式求值实现 本篇名言:"人生不售来回票,一旦动身,绝不能复返." 继续栈应用实现,这次是来看下表达式求值的栈实现. 欢迎转载,转载请标明出处: 1.  表达式求值 表达式求值是设计语言编译中的一个基本问题,它的实现是栈应用的又一个典型例子. 任何一个表达式都是由操作数(Operand).运算符(operator)和界限符(delimiter)组成. 操作数可以是常数也可以是变量或变量的标识符. 运算符可以分为算术运算符.关系运算符和逻辑运算符

C/C++ 语言中的表达式求值

蛱酝缒 C/C++ 语言中的表达式求值

数据结构(7)----栈与队列之栈的应用四则运算表达式求值

栈与队列之栈的应用四则运算表达式求值 栈在四则运算表达式求值的应用为逆波兰表达式(后缀表达式) 普通算式(中缀表达式):9 + (3 - 1) * 3 + 10 / 2     ---(1) 逆波兰表达式(后缀表达式):9 3 1 - 3 * + 10 2 /         ---(2) 1:逆波兰表达式的计算规则 从左到右遍历表达式的每个数字和符号,遇到数字就进栈,遇到符号,就将处于栈顶的两个数字出栈,进行运算,再把运算结果进栈,一直到最终获得结果.接下来我们以(2)式为例:

栈的应用—算术表达式求值

例三.算术表达式求值 1.问题描述 当一个算术表达式中含有多个运算符,且运算符的优先级不同的情况下,如何才能处理一个算术表达式????? 2.思路 首先我们要知道表达式分为三类:  ①中缀表达式:a+(b-c/d)*e ②前缀表达式+a*-be ③后缀表达式abcd/-e*+ 由于运算符有优先级,所以在计算机中计算一个中缀的表达式非常困难,特别是带括号的更麻烦,而后缀表达式中既无运算符优先又无括号的约束问题因为在后缀表达式中运算符出现的顺序正是计算的顺序,所以计算一个后缀的表达式更简单.所以,可

栈的典型应用-表达式求值【转】

本文转载自:http://www.voidcn.com/blog/lub0807/article/p-1510616.html 栈的一个应用是求四则运算表达式的值,这里的表达式包含数字.加减乘除4种运算符,以及小括号. 由于输入是一个字符串,因此解决这个问题需要以下3个步骤: 1.输入字符串转化为中缀表达式: 2.中缀表达式转化为后缀表达式: 3.后缀表达式求值. 现在表达式为:9 + ( 3 - 1 )* 3 + 10 / 2 ,先看一下运行结果: 首先解释一下中缀表达式和后缀表达式的概念.所

c++:栈的应用之表达式求值

Stack.hpp #pragma once template <class T> class Stack{ private: T* _array; size_t _capacity; int _topindex; public: Stack()          //构造函数 :_array(0) , _capacity(0) , _topindex(-1) {} void Push(const T& x){                         //入栈操作 if (_t

数据结构 算法3.4(栈的应用) 表达式求值(stl版and数组模拟版)

问题是 输入一串表达式 其中包括 数字 和各种运算符(   +,-,*,/,(,) ) 求它的值 如 4+(5+2*7)*3 stl版: #include<iostream> #include<cstdio> #include<cstring> #include<stack> using namespace std; int operate(int a,char op,int b) { if(op=='+') return a+b; if(op=='-')

【数据结构】栈的应用——中缀表达式求值(c++)

头文件: #pragma once #include <iostream> #include <assert.h> #include <string> using namespace std; template<class Type> class SeqStack { public: SeqStack(size_t sz = INIT_SZ); ~SeqStack(); public: bool empty()const; bool full()const;