数据结构4.2:栈实现计算器

栈实现计算器

基本思路:

创建两个栈,一个用来装数字一个用来装符号

1,遍历表达式
2,数字入数栈
3,如果是符号则分情况

如果优先级较低则直接对栈顶两个数运算,运算结果再入栈

若优先级较高或是符号栈为空将符号入栈,等待后续

4,表达式全部入栈后,依次从栈中出栈数字和符号进行运算,直到剩下最后一个结果.

完整流程如下

以3*2+3为例

3入栈,2入栈,*入栈(符号栈为空)

遍历到’+‘,’+‘优先级低于’*’

所以弹出3和2,弹出* ,计算3*2,将运算结果6入栈

最后弹出6和3计算6+3得出结果9

最后是代码

基本属性

double[] number = new double[20];
int topn = -1;
char[] cal = new char[20];
int topc = -1;

入数字栈

public void pushn(double input) {
    topn++;
    number[topn] = input;
    System.out.printf("数字入栈%.2f\n", number[topn]);
}

入符号栈

public void pushc(char input) {
    topc++;
    cal[topc] = input;
    System.out.printf("符号入栈%c\n", cal[topc]);
}

出数字栈

public double popn() {
    double op = number[topn];
    System.out.printf("数字出栈%.2f\n", op);
    topn--;
    return op;
}

出符号栈

public char popc() {
    char op = cal[topc];
    System.out.printf("符号出栈%c\n", cal[topc]);
    topc--;
    return op;
}

接下来是重头戏


主要计算方法

public void calculate(String input) {
    for (int i = 0; i < input.length(); i++) {
        char in = input.charAt(i);
        switch (in) {
            case '*':
                if ((topn>=1&&topc!=-1)&&(cal[topc] == '*' || cal[topc] == '/')) {//判断优先级和符号栈是否为空
                    if(cal[topc] == '*'){
                        double temp = popn() * popn();//弹出两个数并计算
                        System.out.println(temp + "运算结果入栈");
                        popc();//符号出栈
                        pushn(temp);//结果入栈
                    }else{
                        double temp = 1/popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushn(temp);
                    }
                } else {
                    pushc('*');
                }
                break;
            case '/':
                if ((topn>=1&&topc!=-1)&&(cal[topc] == '*' || cal[topc] == '/')) {//判断优先级和符号栈是否为空
                    if(cal[topc] == '*'){
                        double temp = popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushn(temp);
                    }else{
                        double temp = 1/popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushn(temp);
                    }
                } else {
                    pushc('/');
                }
                break;
            case '+':
                if (topn>=1&&topc!=-1) {//判断符号栈是否为空
                    if(cal[topc] == '*'){
                        double temp = popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('+');
                        pushn(temp);
                    }else if(cal[topc] == '/'){
                        double temp = 1/popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('+');
                        pushn(temp);
                    }else if(cal[topc] == '+'){
                        double temp = popn() + popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('+');
                        pushn(temp);
                    }else{
                        double temp = -popn() + popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('+');
                        pushn(temp);
                    }
                }else{
                    pushc('+');
                }
                break;
            case '-':
                if (topn>=1&&topc!=-1) {//判断符号栈是否为空
                    if(cal[topc] == '*'){
                        double temp = popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('-');
                        pushn(temp);
                    }else if(cal[topc] == '/'){
                        double temp = 1/popn() * popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('-');
                        pushn(temp);
                    }else if(cal[topc] == '+'){
                        double temp = popn() + popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('-');
                        pushn(temp);
                    }else{
                        double temp = -popn() + popn();
                        System.out.println(temp + "运算结果入栈");
                        popc();
                        pushc('-');
                        pushn(temp);
                    }
                }else{
                    pushc('-');
                }
                break;
            default:
                pushn(in-48);
        }
    }
    System.out.println("字符串遍历完成");
    while (topn != 0&&topc!= -1) {//将第一轮处理后的结果进行运算直到剩下最终结果
        switch (cal[topc]) {
            case '+':
                double temp = popn() + popn();
                System.out.println(temp + "运算结果入栈");
                popc();
                pushn(temp);
                break;
            case '-':
                temp = -popn() + popn();
                System.out.println(temp + "运算结果入栈");
                pushn(temp);
                popc();
                break;
            case '*':
                temp = popn() * popn();
                System.out.println(temp + "运算结果入栈");
                pushn(temp);
                popc();
                break;
            case '/':
                temp = 1/popn() * popn();
                System.out.println(temp + "运算结果入栈");
                pushn(temp);
                popc();
                break;
        }
    }
    System.out.println("最后结果为"+number[topn]);
}

总结:

这里主要是不带括号的计算器

带括号的基本思路大体类似,即将左括号设置为最高优先级,直接入栈,右括号设置为最低优先级,遍历到直接弹出数据进行运算.

计算器实现思路较为巧妙,主要依靠对栈数据结构的理解,理解了就很难忘记.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值