“手撕栈“之“手撕逆波兰计数器”,面试前过自己手撕一遍

目录

手撕栈+普通计数器(中缀求解) 

栈应用之逆波兰计数器(后缀)


 

手撕栈+普通计数器(中缀求解) 

package com.Cx_330.run;

public class StackKKK {
    public int top=-1;
    public int maxSize;
    public int[] stK;
    public StackKKK(int maxSize){
        this.maxSize=maxSize;
        this.stK=new int[maxSize];
    }
    //判断是否为空
    public boolean isEmpty(){
        return top==-1;
    }
    //判断是否满
    public boolean isFull(){
        return top==maxSize-1;
    }
    //添加元素
    public void add(int num){
        if(this.isFull()){
            System.out.println("元素满了");
        }
        top++;
        stK[top]=num;
    }
    //取出栈顶元素并返回
    public int getTop(){
        int val=stK[top];
        top--;
        return val;
    }
    //判断是否为操作符
    public boolean isOper(char ch){
        return ch=='+'||ch=='-'||ch=='*'||ch=='/';
    }
    //返回优先级
    public int priority(char ch){
        if(ch=='*'||ch=='/'){
            return 1;
        }else if (ch=='+'||ch=='-'){
            return 0;
        }
        else {
            return -1;
        }
    }
    //遍历栈元素
    public void show(){
        while (!this.isEmpty()){
            System.out.println(this.getTop());
        }
    }
    public static void main(String[] args) {
        StackKKK numberK = new StackKKK(10);
        StackKKK operK = new StackKKK(10);
        String s="10*3/5+3-4";
        int num1=0;
        int num2=0;
        int res=0;
        char oper;
        char ch;
        int index=0;
        String keepNumber="";
        while (true){
            if(index>=s.length()){
                break;
            }
            ch = s.substring(index, index + 1).charAt(0);
            if(operK.isOper(ch)){
                if(operK.isEmpty()){
                    operK.add(ch);
                }else {
                    if(operK.priority(ch)>operK.priority((char)operK.peek())){
                        operK.add(ch);
                    }else {
                         num1=numberK.getTop();
                         num2=numberK.getTop();
                         oper=(char) operK.getTop();
                         res=cal(num1,num2,oper);
                         numberK.add(res);
                         operK.add(ch);
                    }
                }
            }else {
                keepNumber+=ch;
                if(index==s.length()-1){
                    numberK.add(Integer.parseInt(keepNumber));
                }else {
                    char c = s.substring(index + 1, index + 2).charAt(0);
                    if(numberK.isOper(c)){
                        numberK.add(Integer.parseInt(keepNumber));
                        keepNumber="";
                    }
                }
            }
            index++;
        }
        while (true){
            while (!operK.isEmpty())
            {
                num1=numberK.getTop();
                num2=numberK.getTop();
                oper=(char) operK.getTop();
                res=cal(num1,num2,oper);
                numberK.add(res);
            }
            System.out.println("运算的结果是: "+numberK.getTop());
            break;
        }
    }
    //查看栈顶元素
    private int peek() {
        return stK[top];
    }
    //计算
    public static int cal(int num1,int num2,char oper){
        switch (oper){
            case '+':
                return num1+num2;
            case '-':
                return num2-num1;
            case '*':
                return num1*num2;
            case '/':
                return num2/num1;
            default:
                System.out.println("非法符号");
                return -99999;
        }
    }
}


 

栈应用之逆波兰计数器(后缀)

package com.Cx_330.run;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

public class BoLan {
    public static void main(String[] args) {
        String expression ="1+((2+3)*4)-5";
        List<String> inFIxlist = toInfixExpressionList(expression);
        //中缀字符串转为集合
        System.out.println(inFIxlist);
        //中缀集合转为后缀集合(逆波兰表达式)
        List<String> sufList = parseSuffixExpressionList(inFIxlist);
        System.out.println(sufList);
        //计算结果
        System.out.println(calculate(sufList));
        //[1 2 3 + 4 * + 5 -]
    }

    private static int calculate(List<String> sufList) {
        int res=0;
        int num1;
        int num2;
        char oper;
        Stack<String> stack = new Stack<>();
        for (String c:sufList){
            if(c.matches("\\d+")){
                stack.add(c);
            }else {
                num1=Integer.parseInt(stack.pop());
                num2=Integer.parseInt(stack.pop());
                if(c.equals("+")){
                    res=num1+num2;
                    stack.add(""+res);
                }else if(c.equals("-")){
                    res=num2-num1;
                    stack.add(""+res);

                }else if(c.equals("*")){
                    res=num1*num2;
                    stack.add(""+res);

                }else {
                    res=num2/num1;
                    stack.add(""+res);

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

    private static List<String> parseSuffixExpressionList(List<String> inFIxlist) {
        ArrayList<String> list = new ArrayList<>();
        Stack<String> stack = new Stack<>();
        int num1;
        int num2;
        int res;
        char oper;
        int index=0;
        while (true){
            if(index>=inFIxlist.size()){
                break;
            }
            oper=inFIxlist.get(index).charAt(0);
            if(oper>=48&&oper<=58){
                list.add(""+oper);
                index++;
            }else {
                if(stack.empty()||oper=='('){
                    stack.add(""+oper);
                    index++;
                }else if(oper==')'){
                    while (index<inFIxlist.size()&&(!(stack.peek().equals("(")))){
                        list.add(stack.pop());
                        index++;
                    }
                    stack.pop();
                }else {
                    if(stack.peek().equals("(")){
                        stack.add(""+oper);
                        index++;
                    }
                    else {
                        if(priority(""+oper)<=priority(stack.peek())){
                            list.add(stack.pop());
                            index++;
                        }
                        stack.add(""+oper);
                    }
                }
            }
        }
        while (!stack.empty())
        {
            list.add(stack.pop());
        }
        return list;
    }

    private static List<String> toInfixExpressionList(String expression) {
        ArrayList<String> list = new ArrayList<>();
        int index=0;
        String keep="";
        while (index<expression.length()){
            char ch=expression.substring(index,index+1).charAt(0);
            if(ch<48||ch>58){
                //说明不是数字  直接加入到集合
                list.add(""+ch);
                index++;
            }else {
                //要是数字  要判断是否是多位的数字
                if(index==expression.length()-1){
                    list.add(""+ch);
                    break;
                }else {
                    keep+=ch;
                    char c=expression.substring(index+1,index+2).charAt(0);
                    if(c<48||c>58){
                        list.add(keep);
                        keep="";
                        index++;
                    }else {
                        keep+=c;
                    }
                }
            }
        }
        return list;
    }
    private static int priority(String oper){
        switch (oper){
            case "+":
            case "-":
                return 0;
            case "*":
            case "/":
                return 1;
            default:
                return -1;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C_x_330

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值