学习笔记-算法-4-栈

18 篇文章 0 订阅

  • 先入后出
代码实现栈
class ArrayStack{
    private int maxSize;     // 栈大小
    private int[] stack;    // 数组模拟栈
    private int top = -1;   //栈顶,初始化-1
    
    public ArrayStack(int maxSize){
        this.maxSize = maxSize;
        this.stack = new int[this.maxSize];
    }
    
    // 栈满
    public boolean isFull(){
        return this.top == maxSize-1; 
    }
    // 栈空
    public boolean isEmpty(){
        return this.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 list(){
        if(isEmpty()){
           System.out.println("栈空");
           return;
        }
        for(int i=top;i>=0;i--){
             System.out.println(stack[i]);
        }
    }
    
}
计算器(中缀表达式)
public class Calculator{
    public static void main(String[] args){
        String expression = "3+2*6-2";
        ArrayStack numStack = new ArrayStack(20);
        ArrayStack operStack = new ArrayStack(10);
        int index = 0;      // 用于扫描
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = '';       //每次扫描得到的char保存到ch
        String keepNum = "";
        while(true){
            ch = expression.chartAt(index);
            // 判断
            if(operStack.isOper(ch)){
                // 运算符
                if(!operStack.isEmpty()){    // 符号栈内是否为空
                    // 不为空
                    if(operStack.priority(ch) <= operStack.priority(operStack.peek)){
                        // 优先级小与已存入栈内的值,开始计算已存入数据
                        num1 = numStack.pop();
                        num2 = nmuStack.pop();
                        oper = operStack.pop();
                        res = numStack.cal(num1,num2,oper);
                        // 计算结果压入
                        numStack.push(res);
                        // 将当前符号压入
                        operStack.push(ch);
                    }else{
                        operStack.push(ch);
                    }
                    
                }else{
                    // 为空 直接加入
                    operStack.push(ch);
                }
            }else{
                // numStack.push(ch-48);
                // 处理多位数,index后一位是数字,继续获取
                keepNum += ch;
                if(index==expression.length()-1){
                     numStack.push(Integer.parseInt(keepNum));
                }else{
                    // 判断下一个
                    if(operStack.isOper(expression.charAt(index+1))){
                        numStack.push(Integer.parseInt(keepNum));
                        keepNum = "";
                    }
                }
                
            }
            index++;
            if(index>=expression.length()){
                break;
            }
        }
        while(true){
            // 如果符号栈为空,就是数栈内的一个值
            if(operStack.isEmpty()){
                break;
            }
            num1 = numStak.pop();
            num2 = numStack.pop();
            oper = operStack.pop();
            res = numStack.cal(num1,num2,oper);
            numStack.push(res);
        }
        
        int res2 = numStack.pop();
        System.outprintf("%s=%d",expression,res2);
    }
}

class ArrayStack{
    private int maxSize;     // 栈大小
    private int[] stack;    // 数组模拟栈
    private int top = -1;   //栈顶,初始化-1
    
    public ArrayStack(int maxSize){
        this.maxSize = maxSize;
        this.stack = new int[this.maxSize];
    }
    // 返回当前栈顶值,但不出栈
    public int peek(){
        return stack[top];
    }
    
    // 栈满
    public boolean isFull(){
        return this.top == maxSize-1; 
    }
    // 栈空
    public boolean isEmpty(){
        return this.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 list(){
        if(isEmpty()){
           System.out.println("栈空");
           return;
        }
        for(int i=top;i>=0;i--){
             System.out.println(stack[i]);
        }
    }
    
    // 运算符优先级
    // 数字越大,优先级越高
    // 只考虑+ - * /
    public int priority(int oper){
        if(oper == '*' || oper == '/'){
            return 1;
        }else if(oper =='+' || oper =='-'){
            return 0;
        }else{
            return -1;
        }
    }
    // 判断是否是运算符
    public booleam isOper(char val){
        return val == '+' || val== '-' || val == '*' || val == '/';
    }
    
    // 计算
    public int cal(int num1,int num2,int oper){
        int res = 0;
        switch(oper){
            case '+': res = num1+num2;break;
            case '-': res = num1-num2;break;
            case '*': res = num1*num2;break;
            case '/': res = num1/num2;break;
            default:break;
        }
        return res;
    }
}
计算器(后缀表达式)
  • 逆波兰表达式
    • 后缀表达式
  • 中缀表达式
    • (3+4)*5-6
  • 前缀表达式
          • 3 4 5 6
  • 后缀表达式
    • 3 4 + 5 * 6 -

public class PolandNation{
    public static void main(Styring[] args){
        // 定义逆波兰表达式
        String suffixExpression = "3 4 +  5 * 6 -"; 
        List<String> rpnList = getList(suffixExpression);
        int res = calculate(list);
    }
    
    // 将表达式放入ArrayList
    public static List<String> getListString(String suffixExpression){
        // 将suffixExpression分割
        String[] split = suffixExpression.split(" ");
        List<String> lsit = new ArrayList<String>();
        for(Stringe ele : split){
            list.add(ele);
        }
        return list;
    }
    
    // 运算
    public static int calculate(List<String> ls){
        Stack<String> stack = new Stack<String>();
        for(String item : ls){
            if(item.matches("\\d+")){// 匹配多位数
                stack.push(item);
            }else{
                // pop两个数并运算
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                int res = 0;
                if(item.equals("-")){
                    res = num1+num2;
                }else if(item.equals("-")){
                    res num1 - num2;
                }else if(item.equals(*)){
                    res = num1* num2;
                }else if(item.equals("/")){
                    res = num1 / num2;
                }else{
                    throw new RuntimeException("运算符有误");
                }
                stack.push(""+res)
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

中缀转后缀
public class Demo{
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    // 将中缀表达式对应的list转后缀
    public static List<String> parseSuffixExpressionList(List<String> ls){
        // 初始化栈
        Stack<String> s1 = new Stack<String>();
        List<String> s2 = new List<String>();
        // 遍历ls
        for(String item : ls){
            // 如果是一个数,加入s2
            if(item.matches("\\d+")){
                s2.add(item);
            }else if(item.equals("(")){
                s1.push(item);
            }else if(item.equals(")")){//"()"加入s2
                while(!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();   //将”(“弹出
            }else{
                // 当item优先级小于等于s1栈顶,s1栈顶压入s2
                while(s1.size()!=0 && getOperValue(s1.peek())>= getOperValue(item)){
                    s2.add(s1.pop());
                }
                // item压入
                s1.push(item);
            }
        }
        // 将s1剩余的压入s2
        while(s1.size()!=0){
            s2.add(s1.pop());
        }
        
        return s2;// s2即为对应的后缀表达式
    }
    
    // 中缀转List
    pulic static List<String> toInfixExpressionList(String s){
        List<String> ls = new ArrayList<String>();
        int i=0;
        String str;
        char c;
        do{
            
            // 如果非数字,加入ls
            if((c=s.charAt(i)))=<48 || (c=s.charAt(i)))>57){
                ls.add(""+c);
                i++
            }else{
                // 如果是一个数
                str  = "";
                while(i<s.length()&& (c=s.charAt(i))>=48 && (c=s.charAt(i))<=57){
                    str += c;
                    i++;
                }
                ls.add(str);
            }
        }while(i<s.length());
        return ls;
    }
    
    // 判断优先级高低,返回对应运算符
    public static int getOperValue(String operation){
        int result = 0;
        switch(operation){
            case "+":result = ADD;break;
            case "-":result = ADD;break;
            case "*":result = ADD;break;
            case "/":result = ADD;break;
            default: System.out.println("不存在该运算符"); break;
        }
        return result;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值