第五章、栈(数组模拟栈、链栈、逆波兰表达式、中缀表达式、后缀表达式)

数组模拟栈

public class ArrayStack {
    private int maxSize;
    private int[] stack;
    private int top = -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("栈满,入栈失败");
            return;
        }

        top++;
        stack[top] = value;
    }

    //出栈
    public int pop(){
        if (isEmpty())
            throw new RuntimeException("栈空,出栈失败");

        int value = stack[top];
        top--;
        return value;
    }

    //遍历栈(从栈顶开始)
    public void show(){
        if (isEmpty()){
            System.out.println("栈空");
            return;
        }

        for (int i = top; i >= 0; i--) {
            System.out.println("stack[" + i + "] = " + stack[i]);
        }
    }
}

测试

public class test {
    public static void main(String[] args) {
        String key = "";
        ArrayStack stack = new ArrayStack(4);
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("show:展示栈中元素");
            System.out.println("push:入栈");
            System.out.println("pop:出栈");
            System.out.println("exit:退出");
            System.out.println("请输入你的选择:");
            key = sc.next();

            switch (key){
                case "show":
                    stack.show();
                    break;
                case "push":
                    System.out.println("请输入一个数:");
                    int value = sc.nextInt();
                    stack.push(value);
                    break;
                case "pop":
                    try {
                        int n = stack.pop();
                        System.out.println("出栈的元素为:" + n);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "exit":
                    sc.close();
                    System.out.println("退出成功");
                    return;
                default:
                    break;
            }
        }
    }
}

链栈

节点类

public class HeroNode {
    private int no;
    private HeroNode next = null;

    public HeroNode(int no) {
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public HeroNode getNext() {
        return next;
    }

    public void setNext(HeroNode next) {
        this.next = next;
    }
}

链栈

public class LinkedStack {
    private HeroNode head = new HeroNode(0);

    //入栈
    public void push(int value){
        HeroNode temp = new HeroNode(value);
        temp.setNext(head.getNext());
        head.setNext(temp);
    }

    //出栈
    public int pop(){
        if (head.getNext() == null)
            throw new RuntimeException("栈为空,出栈失败");

        int value = head.getNext().getNo();
        head.setNext(head.getNext().getNext());
        return value;
    }

    //遍历
    public void show(){
        if (head.getNext() == null){
            System.out.println("栈为空");
            return;
        }

        HeroNode temp = head.getNext();
        int n = 0;
        while (temp != null){
            n++;
            System.out.println("stack[" + n + "] = " + temp.getNo());
            temp = temp.getNext();
        }
    }
}

测试

public class LinkedStackTest {
    public static void main(String[] args) {
        String key = "";
        LinkedStack stack = new LinkedStack();
        Scanner sc = new Scanner(System.in);
        while (true){
            System.out.println("show:展示栈中元素");
            System.out.println("push:入栈");
            System.out.println("pop:出栈");
            System.out.println("exit:退出");
            System.out.println("请输入你的选择:");
            key = sc.next();

            switch (key){
                case "show":
                    stack.show();
                    break;
                case "push":
                    System.out.println("请输入一个数:");
                    int value = sc.nextInt();
                    stack.push(value);
                    break;
                case "pop":
                    try {
                        int n = stack.pop();
                        System.out.println("出栈的元素为:" + n);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "exit":
                    sc.close();
                    System.out.println("退出成功");
                    return;
                default:
                    break;
            }
        }
    }
}

逆波兰表达式计算器

public class ArrayStack2 {
    private int maxSize;
    private int[] stack;
    private int top = -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("栈满,入栈失败");
            return;
        }

        top++;
        stack[top] = value;
    }

    //出栈
    public int pop(){
        if (isEmpty())
            throw new RuntimeException("栈空,出栈失败");

        int value = stack[top];
        top--;
        return value;
    }

    //遍历栈(从栈顶开始)
    public void show(){
        if (isEmpty()){
            System.out.println("栈空");
            return;
        }

        for (int i = top; i >= 0; i--) {
            System.out.println("stack[" + i + "] = " + stack[i]);
        }
    }

    //显示栈顶元素
    public int peek(){
        if (isEmpty())
            throw new RuntimeException("栈为空");

        return stack[top];
    }

    //判断优先级
    public int priority(int num){
        if (num == '+' || num == '-')
            return 0;
        else if (num == '*' || num == '/')
            return 1;
        else
            return -1;
    }

    //判断是否是运算符
    public boolean isOper(int num){
        return num == '+' || num == '-' || num == '*' || num == '/';
    }

    //计算结果
    public int cal(int num1, int num2, int oper){
        switch (oper){
            case '+':
                return num1 + num2;
            case '-':
                return num2 - num1;
            case '*':
                return num1 * num2;
            case '/':
                return num2 / num1;
            default:
                break;
        }
        return 0;
    }
}

计算器

public class Calculator {
    public static void main(String[] args) {
        String key = "70*2*2-5+1-5+3-3";

        ArrayStack2 numStack = new ArrayStack2(10);
        ArrayStack2 operStack = new ArrayStack2(10);

        int Index = 0;
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' ';
        String keepNum = "";

        while (Index < key.length()) {
            ch = key.substring(Index, Index + 1).charAt(0);
            if (operStack.isOper(ch)) {
                if (operStack.isEmpty()) {
                    //如果运算符栈为空,则运算符直接入栈
                    operStack.push(ch);
                } else {
                    //如果运算符栈不空,则将运算符栈中优先级大于此运算符的运算符全部弹出,并在数栈中弹出两个数参与运算,并将结果入数栈
                    while (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
                        num1 = numStack.pop();
                        num2 = numStack.pop();
                        oper = operStack.pop();
                        res = numStack.cal(num1, num2, oper);
                        numStack.push(res);

                    //若所有运算符都被弹出栈则直接进栈
                        if (operStack.isEmpty())
                            break;
                    }
                    operStack.push(ch);
                }
            } else {
                keepNum += ch;  //  700)    70+2)   7)
                //可能有多位数参与运算,所以如果是数,继续扫描到后面第一个运算符前面的数字字符当成一个整体入栈
                while (true){
                    if (Index == key.length() - 1)
                        break;
                    Index++;
                    ch = key.substring(Index, Index + 1).charAt(0);
                    if (!operStack.isOper(ch))
                        keepNum += ch;
                    else {
                        Index--;
                        break;
                    }
                }
                numStack.push(Integer.parseInt(keepNum));
                keepNum = "";
            }
            Index++;
        }

        while (!operStack.isEmpty()){
            num1 = numStack.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.cal(num1, num2, oper);
            numStack.push(res);
        }

        System.out.println("计算结果为:" + numStack.pop());
    }
}

中缀表达式的计算和后缀表达式的计算

判断优先级

public class Operation {
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    public static int priority(String key){
        int res = 0;
        switch (key) {
            case "+":
                res = ADD;
                break;
            case "-":
                res = SUB;
                break;
            case "*":
                res = MUL;
                break;
            case "/":
                res = DIV;
                break;
            default:
                System.out.println("运算符有误");
                break;
        }
        return res;
    }
}

主类

/**
 * 完成计算后缀表达式的值
 * 完成将中缀表达式转化成后缀表达式,并求值
 */

public class PolandNotation {
    public static void main(String[] args) {
        //String suffixExpression = "30 4 + 5 * 6 -";
//        String suffixExpression = "4 5 * 8 - 60 + 8 2 / +";
//
//        List<String> list = tolist(suffixExpression);
//        System.out.println("list[] = " + list);
//
//        int res = calculator(list);
//        System.out.println("计算结果为:" + res);
        String infixExpression = "1+((2+3)*4)-5";
        List<String> infixList = toInfixExpressionList(infixExpression);
        System.out.println("中缀表达式为:" + infixList);

        List<String> suffixList = parsesuffixExpressionList(infixList);
        System.out.println("后缀表达式为:" + suffixList);

        System.out.println("计算结果为:" + calculator(suffixList));


    }

    //将中缀表达式转化成后缀表达式
    public static List<String> parsesuffixExpressionList(List<String> infixList) {
        Stack<String> s1 = new Stack<>();
        List<String> s2 = new ArrayList<>();

        for (String temp : infixList) {
            if (temp.matches("\\d+")) {
                s2.add(temp);
            } else if (temp.equals("(")) {
                s1.push(temp);
            } else if (temp.equals(")")) {
                while (!s1.peek().equals("(")) {
                    s2.add(s1.pop());
                }
                s1.pop();
            } else {
                while (!s1.isEmpty() && !s1.peek().equals("(")) {
                    if (Operation.priority(temp) > Operation.priority(s1.peek())) {
                        break;
                    } else {
                        s2.add(s1.pop());
                    }
                }
                s1.push(temp);
            }
        }

        while (!s1.isEmpty()){
            s2.add(s1.pop());
        }
        return s2;
    }


    //将字符串中缀表达式放到List中存储
    public static List<String> toInfixExpressionList(String infixExpression) {
        List<String> list = new ArrayList<>();
        int i = 0;
        char c;
        String string;

        while (i < infixExpression.length()) {
            c = infixExpression.charAt(i);
            if (c < 48 || c > 57) {
                list.add("" + c);
                i++;
            } else {
                string = "";
                while (i < infixExpression.length() && (c = infixExpression.charAt(i)) >= 48
                        && (c = infixExpression.charAt(i)) <= 57) {
                    string += c;
                    i++;
                }
                list.add(string);
            }
        }

        return list;
    }


    //将逆波兰表达式放到ArrayList里去
    public static List<String> tolist(String suffixExpression) {
        String[] split = suffixExpression.split(" ");
        List<String> list = new ArrayList<>();

        for (String temp : split) {
            list.add(temp);
        }

        return list;
    }

    //计算逆波兰表达式
    public static int calculator(List<String> list) {
        Stack<String> stack = new Stack<>();
        for (String temp : list) {
            if (temp.matches("\\d+")) {
                stack.push(temp);
            } else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int res = 0;
                if (temp.equals("+")) {
                    res = num2 + num1;
                } else if (temp.equals("-")) {
                    res = num2 - num1;
                } else if (temp.equals("*")) {
                    res = num2 * num1;
                } else if (temp.equals("/")) {
                    res = num2 / num1;
                } else {
                    throw new RuntimeException("运算符有误");
                }
                //System.out.println(res);
                stack.push("" + res);
            }
        }

        return Integer.parseInt(stack.pop());
    }


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值