【数据结构】07-栈(stack)

一、应用场景

在这里插入图片描述

二、数组模拟栈

在这里插入图片描述

package cn.qqqking.stack;


import java.util.Scanner;


/**
* @author AnQi
* @date 2020/4/15 15 59:55
* @description
*/
public class ArrayStackDemo {
    public static void main(String[] args) {


        //测试
        ArrayStack stack = new ArrayStack(4);
        String key=" "; //接收用户输入
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        //输出菜单
        while(loop){


            System.out.println("show:显示");
            System.out.println("exit:退出");
            System.out.println("push:添加");
            System.out.println("pop:出栈");
            System.out.println("请输入操作:");
            key = scanner.next(); //接收一个字符


            switch(key){


                case "show":
                    try{
                        stack.list();
                    }catch(Exception e){
                        System.out.println( e.getMessage());
                    }
                    break;
                case "exit":
                    scanner.close();
                    loop =false;
                    break;
                case "push":
                    try{
                        System.out.println("输入一个数");
                        int value = scanner.nextInt();
                        stack.push(value);
                    }catch(Exception e){
                        System.out.println( e.getMessage());
                    }
                    break;
                case "pop":
                    try{
                        int pop = stack.pop();
                        System.out.printf("出栈的数据为:%d \n",pop);
                    }catch(Exception e){
                        System.out.println( e.getMessage());
                    }
                    break;


                default:
                    System.out.println("指令输入有误 请重新输入");
                    break;
            }
        }
        System.out.println("退出程序");


    }
}
//定义一个array 表示栈
class ArrayStack {
    private int maxSize; //栈的大小
    private int[] stack; //数组 模拟栈 数据存放在数组
    private int top = -1; //指向栈顶 无数据 默认为-1


    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int [this.maxSize];
    }


    //栈满
    public boolean isFull(){
       return top == maxSize-1;
    }
    //栈空
    public boolean isEmpty(){
        return top == -1;
    }
    //入栈
    public void push(int value){
        //判断是否为满
        if(isFull()){
            System.out.println("满了!!");
        }else{
            top++;
            stack[top]=value;
        }


    }
    //出栈 将栈顶数据返回
    public int pop(){
        //判断是否为空
        if(isEmpty()){
            //抛出异常
            throw new RuntimeException("栈为空!!!");
        }
        int value = stack[top];
        top--;
        return value;
    }


    //遍历栈 需要从栈顶开始遍历数据
    public void list(){
        //判断是否为空
        if(isEmpty()){
            //抛出异常
            throw new RuntimeException("栈为空!!!");


        }
        for(int i = top;i>=0;i--){
            System.out.printf("stack[%d]=%d\n",i,stack[i]);
        }
    }

}

三、栈实现综合计算器

package cn.qqqking.stack;

/**
* @author AnQi
* @date 2020/4/15 16 46:34
* @description
*/
public class Calculator {
    public static void main(String[] args) {
        //Test
        String expression = "700+2*6-4";
        //创建两个栈 数字 符号
        ArrayStack2 numStack = new ArrayStack2(10);
        ArrayStack2 operaStack = new ArrayStack2(10);
        //定义需要的相关变量
        int index = 0; //用于扫描
        int num1 = 0;
        int num2 = 0;
        int opera = 0;
        int res = 0;
        char ch = ' '; //将每次扫描的char保存到ch
        String keepNum="";
        //扫描 表达式
        while(true){
            //得到
            ch = expression.substring(index,index+1).charAt(0);
            //判断 ch是什么 做相应 存入对应数组中
            if(operaStack.isOpera(ch)){
                //判断当前栈 是否为空
                if(!operaStack.isEmpty()){
                    /**
                     * 栈当前有操作符 进行比较
                     * 如果当前操作符优先级小于等于栈中操作符
                     * 则 从数字栈中取出两个数字
                     * 从符号栈中取出一个符号 进行运算
                     * 结果放入数栈
                     * 将需要符号放入符号栈
                     */
                    if(operaStack.priority(ch) <= operaStack.priority(operaStack.peek())){
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        opera  = operaStack.pop();
                        res  = numStack.cal(num1,num2,opera);
                        //结果放入数栈
                        numStack.push(res);
                        //符号放入符号栈
                        operaStack.push(ch);
                    }else{
                        /**
                         * 当前的操作等级大于栈顶的
                         * 直接放入符号栈
                         */


                        operaStack.push(ch);
                    }
                }else{
                    //为空直接放入符号栈
                    operaStack.push(ch);
                }
            }else{
                /**
                 * 处理多位数字时 需要index多看一位
                 */
                keepNum += ch;
                //如果ch已经为expression的最后一位 就直接入栈
                if(index == expression.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else{
                    //判断下一个字符是不是数字
                    if(operaStack.isOpera(expression.substring(index+1,index+2).charAt(0))){
                        //如果是运算符则数字结束 将数据存入
                        numStack.push(Integer.parseInt(keepNum));
                        //清空keepNum
                        keepNum="";
                    }
                }
            }
            //index+1 判断是否扫描到最后
            index++;
            if(index >=expression.length()){
                break;
            }
        }


        while(true){
            //如果符号栈为空 则计算到最后结果 数栈中只有一个数字即为结果
            if(operaStack.isEmpty()){
                break;
            }
            num1 = numStack.pop();
            num2 = numStack.pop();
            opera  = operaStack.pop();
            res  = numStack.cal(num1,num2,opera);
            numStack.push(res);
        }
        //结果pop出来
        System.out.printf("表达式%s = %d",expression,numStack.pop());
    }
}

//创建一个栈 直接使用前面的栈

//定义一个array 表示栈
class ArrayStack2 {
    private int maxSize; //栈的大小
    private int[] stack; //数组 模拟栈 数据存放在数组
    private int top = -1; //指向栈顶 无数据 默认为-1


    public ArrayStack2(int maxSize) {
        this.maxSize = maxSize;
        stack = new int [this.maxSize];
    }




    //栈满
    public boolean isFull(){
        return top == maxSize-1;
    }
    //栈空
    public boolean isEmpty(){
        return top == -1;
    }
    //入栈
    public void push(int value){
        //判断是否为满
        if(isFull()){
            System.out.println("满了!!");
        }else{
            top++;
            stack[top]=value;
        }


    }
    //出栈 将栈顶数据返回
    public int pop(){
        //判断是否为空
        if(isEmpty()){
            //抛出异常
            throw new RuntimeException("栈为空!!!");
        }
        int value = stack[top];
        top--;
        return value;
    }


    //遍历栈 需要从栈顶开始遍历数据
    public void list(){
        //判断是否为空
        if(isEmpty()){
            //抛出异常
            throw new RuntimeException("栈为空!!!");


        }
        for(int i = top;i>=0;i--){
            System.out.printf("stack[%d]=%d\n",i,stack[i]);
        }
    }


    //返回运算符的优先级 优先级使用数字表示 数字越大优先级越高
    public int priority(int opera){
        if(opera == '*' || opera== '/'){
            return 1;
        }else if(opera == '+' || opera== '-'){
            return 0;
        }else{
            return -1; //只有加减乘除 其他无效
        }
    }


    //判断是不是一个操作符
    public boolean isOpera(char val)
    {
        return val == '+' || val== '-' || val == '*' || val == '/';
    }
    //运算方法
    public int cal(int num1,int num2,int opera){
        int res=0; //返回结果
        switch(opera){
            case '+':
                res =num1+num2;
                break;
            case '-':
                res = num2 - num1; //注意顺序
                break;
            case '*':
                res = num1 * num2; //注意顺序
                break;
            case '/':
                res = num2 / num1; //注意顺序
                break;
            default:
                break;


        }
        return res;
    }


    //返回当前栈顶的值 不是出栈
    public int peek(){
        return stack[top];
    }




}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值