数据结构与算法day05

栈计算器的代码实现


  最近在备战蓝桥杯的时候,总是感觉追不上别人,和别人进度差了好多,再加上四级也没有通过,在迷茫自己到底行不行,但是我总认为我不应该止步于此,我是主角我想要一个更好的结局,对,千万不要看见别人发光,就觉得自己暗淡,他强任他强,清风拂山岗,生活中,人和人的节奏不一样,所以别碰到一点压力就把自己搞得不堪重负的样子,成功之前,你这辈子该走的弯路,该吃的苦,该撞的南墙,该吃的亏,一个都少不了,放下纠结,考差了再努力,工作丢了再找,钱没了再挣,朋友没了再交,爱情丢了再遇,人生本来就一无所有,有什么事不能从头再来呢?所以不要东张西望,不要受他人影响,只需大胆的往前走,路一直都在脚下。切记他强任他强,清风拂山岗,管他们有多强,与我何干,我只要强过昨天的自己,也是成功,如此想到,便也释怀了,请只顾向前走。


public class Calaculator {
    public static void main(String[] args) {
        //根据思路完成表达式的运算
        String expression = "70+2*6-4";
        //创建两个栈,一个数栈,一个符号栈
        ArryStatck2 numStack = new ArryStatck2(10);
        ArryStatck2 operStack = new ArryStatck2(10);
        //定义相关的变量
        int index = 0;//用于扫描
        int num1 = 0;
        int num2 = 0;
        int oper = 0;
        int res = 0;
        char ch = ' ';//将每次扫描得到的char保存到ch
        String keepNum = "";//用于拼接多位数
        //用while循环扫描expression
        while (true){
            //依次得到expression的每一个字符
            ch = expression.substring(index,index+1).charAt(0);
            //判断ch是什么,然后进行相应的判断
            if (operStack.isOper(ch)){
                //如果是运算符
                //判断符号栈是否为空
                if (!operStack.isEpety()){
                    //如果符号栈有操作符,那么就要进行比较优先级,如果优先级
                    //小于栈中的符号,就要pop出两个数字,符号栈中pop一个符号,进行运算
                    if (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);
                        //把运算符入符号栈
                        operStack.push(ch);
                    }else {
                        //如果当前的操作符大于栈中 的直接入栈
                        operStack.push(ch);
                    }
                }else {
                    //如果栈空那么直接入栈
                    operStack.push(ch);
                }
            }else {
                //如果是数字直接入数栈
                //numStack.push(ch - 48);//因为ch是字符,要减去48才是真正的数字的值
                //当处理多位数时,就不能这样入栈,因为后面还有数字
                //在处理数字时,需要向后再看一位,如果是运算符才能入栈
                //需要一个中间值,用于拼接多位数

                //处理多位数,进行拼接
                keepNum += ch;
                //如果ch已经是最后一位,直接入栈
                if (index == expression.length()-1){
                    numStack.push(Integer.parseInt(keepNum));
                }else {

                    //判断下一个字符是不是符号
                    if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
                        //如果后一位是运算符则入栈
                        numStack.push(Integer.parseInt(keepNum));//要将keepNum变为int型才能如数栈
                        //要将keepNum清空
                        keepNum = "";
                    }
                }
            }
            //让index加一,判断是否扫描到expression最后
            index++;
            if (index >= expression.length()){
                break;
            }
        }
        //当表达式扫描完毕,顺序pop出相应的数和符号,并运行
        while (true){
            if (operStack.isEpety()){//如果符号栈为空,则计算到最后的结果,且数栈中的最后一个元素就是结果
                break;
            }else {
                num1 = numStack.pop();
                num2 = numStack.pop();
                oper = operStack.pop();
                res = numStack.cal(num1,num2,oper);
                //把运算的结果入数栈
                numStack.push(res);
            }
        }  System.out.printf("表达式%s = %d",expression,numStack.pop());
    }
}
class ArryStatck2{
    private int maxsize;
    private int [] statck;//数组模拟栈
    private int top = -1;//表示栈顶,初始值为-1

    //构造器

    public ArryStatck2(int maxsize) {//需要进行扩展,要会进行判断符号的优先级
        this.maxsize = maxsize;
        statck = new int[this.maxsize];//数组只用先初始化才能进行赋值
    }
    //判断是否zhanman
    public boolean isFull(){
        return top == maxsize-1;
    }
    //判断是否栈空
    public boolean isEpety(){
        return top == -1;
    }
    //入栈push
    public void push(int value){//定义一个值
        //队列和栈都要判断是否满
        if (isFull()){
            System.out.println("沾满");
            return;
        }
        top++;
        statck[top] = value;
    }
    //出栈pop
    public int pop(){//出栈要将值显示出来,所以int
        //判断是否空
        if (isEpety()){
            throw new RuntimeException();
        }
        int value = statck[top];//出栈是先赋值
        top--;
        return value;
    }
    //显示栈的情况
    public void show(){
        if (isEpety()){
            System.out.println("站控,没有数据");
            return;
        }
        //要从栈顶开始显示数据
        for (int i = top;i >= 0;i--){
            System.out.println(statck[i]);
        }
    }
    public int priority(int oper){
        if (oper == '*' || oper == '/'){
            return 1;
        }else if (oper == '+' || oper == '-'){
            return 0;
        }else {
            return -1;//输入错误的运算符
        }
    }
    //判断是不是运算符
    public boolean isOper(char val){
        return val == '+' || val == '-' || val =='*' || val == '/';
    }
    //计算方法

    /**
     *
     * @param num1 传进来的数字1
     * @param num2 数字2
     * @param oper 运算符
     * @return
     */
    public int cal(int num1,int num2,int oper){
        int res = 0;//用于存放计算的结果
        switch (oper){
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1;
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1;//这里减法和除法要注意先后顺序
                break;
        }
        return res;
    }
    public int peek(){//返回栈顶的值,但并不是真正的弹出,用于进行比较
        return statck[top];
    }
}

前缀表达式

  前缀表达式是一种将运算符写在操作数之前的表达式表示方法。例如,中缀表达式 "3 + 4" 可以写成前缀表达式 "+ 3 4"。

逆波兰表达式

  逆波兰表达式(Reverse Polish Notation,RPN)是一种数学表达式的表示方法,其中运算符在操作数的后面而不是中间。逆波兰表达式不需要括号来指示运算的顺序,因为运算符的位置已经明确了每个操作数与其相应的运算符之间的关系。例如,中缀表达式 "3 + 4 * 2" 可以转换为逆波兰表达式 "3 4 2 * +"。

 因为逆波兰表达式和中缀转后缀较为难理解,先暂且搁置,只是先根据老师的思路过了一遍,之后再进行代码实现

递归

  

递归的调用机制 

  在下面的例子中先输出的是最内层的内容,然后逐层向外输出,所以结果是2,3,4而不是4,3,2

 代码

public class RecursionTest {
    public static void main(String[] args) {
        //通过打印问题来初步了解递归
        test(9);
        System.out.println(factoria(10));
    }
    public static void test(int n){
        if (n > 2){
            test(n-1);
        }
        System.out.println(n);
    }
    public static int factoria(int a){//阶乘
        if (a == 1){
            return 1;
        }else {
            return factoria(a-1)*a;
        }
    }
}

递归可以解决什么问题

  各种各样的问题

递归要遵守的规则

 

今日学习到此为止,希望以后可以继续保持 

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

伯谨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值