栈与队列

什么是栈?个人理解栈就好比手枪的子弹夹,“后进先出”,有很多应用栈的地方,例如浏览器中的后退,最经典的应该是逆波兰算法。
什么是队列?个人理解队列就像你打客服电话,由于是高峰时段,你必须先等等待,一个人结束另一个人才能开始,也就是所谓的“先进先出”。
栈都有顺序栈、链栈,队列都有顺序队列、循环队列、链队列。

下面就用逆波兰算法来简单说明栈的应用:
简单说明逆波兰原理
逆波兰算法的核心步骤就2个:
1、将中缀表达式转换为后缀表达式,例如输入的原始表达式是 3*(5+7)(中缀表达) ,转换得到 3 5 7 + *(后缀表达)
2、根据后缀表达式,按照特定的计算规则得到最终结算结果

下面详细介绍这个2步的操作。
中缀表达式转换为后缀表达式
你需要设定一个栈SOP,和一个线性表 L 。SOP用于临时存储运算符和分界符( ,L用于存储后缀表达式。
遍历原始表达式中的每一个表达式元素
(1)如果是操作数,则直接追加到 L中。只有 运算符 或者 分界符( 才可以存放到 栈SOP中
(2)如果是分界符
Ⅰ 如果是左括号 ( , 则 直接压入SOP,等待下一个最近的 右括号 与之配对。
Ⅱ 如果是右括号),则说明有一对括号已经配对(在表达式输入无误的情况下)。不将它压栈,丢弃它,然后从SOP中出栈,得到元素e,将e依次追加到L里。一直循环,直到出栈元素e 是 左括号 ( ,同样丢弃他。
(3)如果是运算符(用op1表示)
Ⅰ如果SOP栈顶元素(用op2表示) 不是运算符,则二者没有可比性,则直接将此运算符op1压栈。 例如栈顶是左括号 ( ,或者栈为空。
Ⅱ 如果SOP栈顶元素(用op2表示) 是运算符 ,则比较op1和 op2的优先级。如果op1 > op2 ,则直接将此运算符op1压栈。
如果不满足op1 > op2,则将op2出栈,并追加到L,重复步骤3。
也就是说,如果在SOP栈中,有2个相邻的元素都是运算符,则他们必须满足:下层运算符的优先级一定小于上层元素的优先级,才能相邻。

最后,如果SOP中还有元素,则依次弹出追加到L后,就得到了后缀表达式。
下面就开始所谓的逆波兰算法:(源码)

package com.cn.hnust.controller;

import java.util.LinkedList;

/**
 * 栈类
 */
public class Stracks {
    private LinkedList linkedList=new LinkedList();
    int top=-1;
    public void push( Object value){//入栈方法
        top++ ;
        linkedList.addFirst(value);
    }
    public Object pop() {//出栈方法
        Object o = linkedList.getFirst();
        top--;
        linkedList.removeFirst();
        return o;
    }
    public Object top(){
        return  linkedList.getFirst();
    }
}
package com.cn.hnust.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;

/**
 * 表达式类中缀变后缀
 */
public class Expression {
    private ArrayList arrayListMid = new ArrayList();//存储中缀表达式
    private ArrayList arrayListLast = new ArrayList(); //存储后缀表达式
    private String  result;


    public Expression(String value) {//根据输入信息创建中缀表达式对象
        StringTokenizer stringTokenizer =new StringTokenizer(value,"+-*/()",true);
        while(stringTokenizer.hasMoreElements()){
           String s = stringTokenizer.nextToken();
           arrayListMid.add(s);
        }
    }

    public  void Last(){//中缀转后缀
        Stracks stracks = new Stracks();//实例化栈类对象,方便调用
        String operator;
        int postion = 0;
        while (true){
            if (Calculate.isOperator((String) arrayListMid.get(postion))) {
                if (stracks.top == -1
                        || ((String) arrayListMid.get(postion)).equals("(")) {
                    stracks.push(arrayListMid.get(postion));
                } else {
                    if (((String) arrayListMid.get(postion)).equals(")")) {
                        while(true){

                            if (stracks.top != -1&&!((String) stracks.top()).equals("(")) {
                                operator = (String) stracks.pop();
                                arrayListLast.add(operator);
                            }else{
                                if(stracks.top != -1)
                                    stracks.pop();
                                break;
                            }
                        }
                    } else {
                        while(true){
                            if (stracks.top != -1&&Calculate.priority((String) arrayListMid
                                    .get(postion)) <= Calculate
                                    .priority((String) stracks.top())
                                    ) {
                                operator = (String) stracks.pop();
                                if (!operator.equals("("))
                                    arrayListLast.add(operator);
                            }else{
                                break;
                            }

                        }
                        stracks.push(arrayListMid.get(postion));
                    }
                }
            } else
                arrayListLast.add(arrayListMid.get(postion));
            postion++;
            if (postion >= arrayListMid.size())
                break;
        }
        while (stracks.top != -1) {
            operator = (String) stracks.pop();
            if(!operator.equals("("))
                arrayListLast.add(operator);
        }
    }

    // 对右序表达式进行求值
    private void getResult() {
        this.Last();
        for(int i=0;i<arrayListLast.size();i++){
            System.out.println(arrayListLast.get(i));
        }
        Stracks aStack = new Stracks();
        String op1, op2, is = null;
        Iterator it = arrayListLast.iterator();

        while (it.hasNext()) {
            is = (String) it.next();
            if (Calculate.isOperator(is)) {
                op1 = (String) aStack.pop();
                op2 = (String) aStack.pop();
                aStack.push(Calculate.twoResult(is, op1, op2));
            } else
                aStack.push(is);
        }
        result = (String) aStack.pop();
        it = arrayListMid.iterator();
        while (it.hasNext()) {
            System.out.print((String) it.next());
        }
        System.out.println("=" + result);
    }

    public static void main(String avg[]) {
        try {
            System.out.println("Input a expression:");
            BufferedReader is = new BufferedReader(new InputStreamReader(
                    System.in));
            for (;;) {
                String input = new String();
                input = is.readLine().trim();
                if (input.equals("q"))
                    break;
                else {
                    Expression boya = new Expression(input);
                    boya.getResult();
                }
                System.out
                        .println("Input another expression or input 'q' to quit:");
            }
            is.close();
        } catch (IOException e) {
            System.out.println("Wrong input!!!");
        }
    }

}
package com.cn.hnust.controller;

public class Calculate {
    // 判断是否为操作符号
    public static boolean isOperator(String operator) {
        if (operator.equals("+") || operator.equals("-")
                || operator.equals("*") || operator.equals("/")
                || operator.equals("(") || operator.equals(")"))
            return true;
        else
            return false;
    }

    // 设置操作符号的优先级别
    public static int priority(String operator) {
        if (operator.equals("+") || operator.equals("-"))
            return 1;
        else if (operator.equals("*") || operator.equals("/"))
            return 2;
        else
            return 0;
    }

    // 做2值之间的计算
    public static String twoResult(String operator, String a, String b) {
        try {
            String op = operator;
            String rs = new String();
            double x = Double.parseDouble(b);
            double y = Double.parseDouble(a);
            double z = 0;
            if (op.equals("+"))
                z = x + y;
            else if (op.equals("-"))
                z = x - y;
            else if (op.equals("*"))
                z = x * y;
            else if (op.equals("/"))
                z = x / y;
            else
                z = 0;
            return rs + z;
        } catch (NumberFormatException e) {
            System.out.println("input has something wrong!");
            return "Error";
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值