算法-双栈之算术表达式

(1+ ( (2+3) * (4 * 5)))

我们如何通过算法来计算上面的表达式呢?

方法:用2个栈(一个用于保存运算符,一个用于保存操作数),其中的运算符包括:+,-,*,/,(,),

表达式有括号、运算符、和操作数(数字)组成。我们根据以下4种情况从左到右逐个将这些实体送入栈处理

将操作数压入操作数栈

将运算符压入运算符栈

忽略左括号

在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈

 

最后:

在处理完最后一个右括号的时候,操作数栈中只会又一个值,他就是表达式的值

package base.第一章.背包_队列_和栈.双栈之算术表达式;

import base.第一章.背包_队列_和栈.下压栈.Stack;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

/**
 * Created by MK on 2018/7/20.
 * 使用双栈,求得算术表达式
 */
public class Evaludate {

    //    循环字符串
    public static Stack<Double> while_str(String str) {
        //创建2个栈,一个存储运算符,一个存储操作数
        Stack<String> ops = new Stack<String>(); //存储运算符
        Stack<Double> vals = new Stack<Double>(); //存储操作数
        for (int i = 0; i < str.length(); i++) {
            char item = str.charAt(i);
            String s = item + "";
            if (s.equals("(")) ; //什么都不做
            else if (s.equals("+")) ops.push(s); //压入到栈中
            else if (s.equals("-")) ops.push(s);
            else if (s.equals("*")) ops.push(s);
            else if (s.equals("/")) ops.push(s);
            else if (s.equals("sqrt")) ops.push(s);

            else if (s.equals(")"))  //在遇到右括号时,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈
            {
                /**
                 * 可这么理解:
                 *  (1+ ( (2+3) * (4 * 5)))
                 *  前提:下压栈后进来的先出去
                 *  op:当我碰到")"的时候,我要将对应的运算符弹出,对应的就是上述公式中的"2+3"中的"+",因为"1+"中的"+"是先压入栈中的
                 *  v:其次在将操作数取出,取出的是上述中的,2+3中的3
                 *  最后当我等于+号的时候,再弹出操作数,此时的操作数就是2,再让其加上,上面公式中取到的3
                 * */
                String op = ops.pop();
                double v = vals.pop();
                if (op.equals("+")) v = vals.pop() + v;
                if (op.equals("-")) v = vals.pop() - v;
                if (op.equals("*")) v = vals.pop() * v;
                if (op.equals("/")) v = vals.pop() / v;
                if (op.equals("sqrt")) v = Math.sqrt(v);

                vals.push(v);//将计算后的值,压入到对应的栈中

            } else
                vals.push(Double.parseDouble(s)); //将操作数压入到栈中
        }
        return vals;
    }

    public static void main(String[] args) {

        /**
         * 注意有大前提
         *  我算术表达式,需要以")"右括号结尾才可进行计算
         *  所传数字如果是2位数的话,就有问题了
         *
         * */

        while (!StdIn.isEmpty()) {
            String s = StdIn.readLine();
            Stack<Double> vals = while_str(s);
            StdOut.println(vals.pop());//在处理完最后一个右括号的时候,操作数栈中只会又一个值,他就是表达式的值
        }

    }
}

猜你喜欢

转载自blog.csdn.net/qq_33982605/article/details/81170533
今日推荐