利用栈对表达式求值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js.js"></script>
</head>
<body>
输入中缀表达式空格分隔 例如 2 + 3
<input type="text" id="input" value=""><input type="button" onclick="fun()" value="计算">
    <div id="aa">

    </div>


<script>
    /*
    *
    * #Re:【js数据结构】栈解决括号不匹配问题
    *
     *一个算术表达式的后缀表达式形式如下: op1 op2 operator
     *使用两个栈,一个用来存储操作数,另外一个用来存储操作符,设计并实现一个 JavaScript 函 数,该函数可以将中缀表达式转换为后缀表达式,然后利用栈对该表达式求值。
     */


    function Stack()
    {
        this.top = 0;
        this.arr = [];
        this.push = push;
        this.pop = pop;
        this.peek = peek;
        this.clear = clear;
        this.len = len;
        this.isEmpty = isEmpty;
    }


    function push(val)
    {
      this.arr[this.top++] = val;
    }

    function pop()
    {
        return this.arr[--this.top];
    }

    function peek(){
        return this.arr[this.top-1];
    }

    function clear(){
        delete this.arr;
        this.top = 0;
        this.arr = [];
    }

    function len(){
        return this.top;
    }



    function  isEmpty() {
        if(this.len() <= 0)
            return true;
        else
            return false;
    }


    function operatorFun(result, val, operator)
    {
        switch (operator)
        {
            case "+":
                return parseInt(result) + parseInt(val);
                break;
            case "-":
                return result - val;
                break;
            case "*":
                return result * val;
                break;
            case "/":
                return result / val;
                break;
        }
    }


    var numStack = new Stack();
    var operatorStack = new Stack();

    function fun() {
        var Str = document.getElementById("input").value;
        strline = Str.split(" ");
        for(var i = 0; i<strline.length; i++)
        {
            if(i%2 == 0)
                numStack.push(strline[i])
            else
                operatorStack.push(strline[i])

        }
        var op, operator, result;

        if(numStack.len()>0)
            result = numStack.pop()
        while(numStack.len()>0 && operatorStack.len()>0)
        {
            operator = operatorStack.pop();
            op = numStack.pop();
            result = operatorFun(result, op, operator)
        }
        console.log(result)
    }

   
</script>
</body>
</html>

  展示如下:

   顺序从右向左,无优先级顺序,图中顺序 4*5=20, 20+4=24,结果为24

 

 

 考虑优先级的运算表达式求值

  以上为不考虑优先级的表达式求值方法,那么接下来考虑优先级时,将考虑:

  •     先乘除
  •     后加减
  •     有括号先算括号里

   换成编程思路:

    执行表达式运算时,总是将结果压入numStack栈

     1. 遇到 “+”、“-” 操作符时,优先级最低,先计算栈内已存数据的加减乘除操作

     2. 遇到 “*” 、“/” 操作符时,计算栈内已存数据的乘除操作

     3. 遇到 “(” 直接入operatorStack

     4. 遇到 “)” 运算栈内的数据,直到找到 “(”

  代码如下:

function operatorFun(numStack, operatorStack)
    {
        var op1, op2, operator;
        op1 = numStack.pop();
        op2 = numStack.pop();
        operator = operatorStack.pop();
        switch (operator)
        {
            case "+":
                numStack.push(parseInt(op2) + parseInt(op1));
                break;
            case "-":
                numStack.push(op2 - op1);
                break;
            case "*":
                numStack.push(op2 * op1);
                break;
            case "/":
                numStack.push(op2 / op1);
                break;
        }
    }

  

  function fun() {
        var Str = document.getElementById("input").value;
        strline = Str.split(" ");
        for(var i = 0; i<strline.length; i++)
        {
            if(strline[i] == "")
            {
                continue;
            }
            else if(strline[i] == "+" ||strline[i] == "-")
            {
                while((operatorStack.len() !=0 ) && (operatorStack.peek() == "+" || operatorStack.peek() == "-"|| operatorStack.peek() == "*" ||operatorStack.peek() == "/"))
                {
                    
                    operatorFun(numStack,operatorStack);

                }
                operatorStack.push(strline[i])
            }
            else if(strline[i] == "*" ||strline[i] == "/")
            {
                while((operatorStack.len() !=0 ) && (operatorStack.peek() == "*" ||operatorStack.peek() == "/"))
                {
                    operatorFun(numStack,operatorStack);
                }
                operatorStack.push(strline[i])
            }
            else if(strline[i] == "(" )
            {
                operatorStack.push('(')
            }
            else if(strline[i] == ")" )
            {
                while(operatorStack.peek() != "(")
                {
                    operatorFun(numStack,operatorStack);
                }
                operatorStack.pop();
            }
            else
            {
                numStack.push(strline[i])
            }

        }

        while(operatorStack.len() != 0)
        {
            operatorFun(numStack,operatorStack);
        }
        console.log(numStack.pop()) ;
    }

  例如:计算 3 * 3 - ( 12 + 3 * 2 ) / 3

              

  欢迎补充。

posted @ 2017-07-06 18:26  卡迪斯上小学  阅读(939)  评论(3编辑  收藏  举报