使用栈实现简单计算器

描述:

输入一串字符串,输出它的计算结果。//考虑输入不正确的情况
例如输入:722-5+1-5+3-4 输出18

代码如下:

public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        Stack<Character>  stack2 = new Stack<>();
        Stack<Integer>  stack1 = new Stack<>();
        int i=0;
        int num = 0;
        //扫描表达式
        for(i=0;i<str.length();i++) {
            if(i==str.length()-1) {
                num = num*10+str.charAt(i)-'0';
                stack1.push(num);
            }
            if((str.charAt(i)>='0')&&(str.charAt(i)<='9')) {
                num = num*10+str.charAt(i)-'0';
            }
            else {
                stack1.push(num);
                num = 0;
                if(stack2.isEmpty()) {
                    stack2.push(str.charAt(i));
                } else if(str.charAt(i)=='+' || str.charAt(i)=='-') {
                    int n2 = stack1.pop();
                    int n1 = stack1.pop();
                    char ch1 = stack2.pop();
                    if(ch1=='+') {
                        stack1.push(n1+n2);
                        stack2.push(str.charAt(i));
                    } else if(ch1=='-') {
                        stack1.push(n1-n2);
                        stack2.push(str.charAt(i));
                    }
                    else if(ch1=='*') {
                        stack1.push(n1*n2);
                        stack2.push(str.charAt(i));
                    }
                    else if(ch1=='/') {
                        stack1.push(n1/n2);
                        stack2.push(str.charAt(i));
                    }
                } else if(str.charAt(i)=='*' || str.charAt(i)=='/') {
                    char ch1 = stack2.pop();
                    if(ch1=='*' || ch1=='/') {//优先级相同
                        int n1 = stack1.pop();
                        int n2 = stack1.pop();
                        if(ch1=='*') {
                            stack1.push(n1*n2);
                            stack2.push(str.charAt(i));
                        }
                        else if(ch1=='/') {
                            stack1.push(n1/n2);
                            stack2.push(str.charAt(i));
                        }
                    }
                    else {//if(ch1=='*' || ch1=='/') //优先级大于
                        stack2.push(str.charAt(i));
                    }
                }
            }
        }
        //表达式扫描完毕后
        while (!stack2.isEmpty()) {
            int n2 = stack1.pop();
            int n1 = stack1.pop();
            char ch1 = stack2.pop();
            if(ch1=='+') {
                stack1.push(n1+n2);
            }
            else if(ch1=='-'){
                stack1.push(n1-n2);
            }
            else if(ch1=='*'){
                stack1.push(n1*n2);
            }
            else if(ch1=='/'){
                stack1.push(n1/n2);
            }
        }
        System.out.println(stack1.pop());
    }

相信很多小伙伴第一次接触这种题目一般题目都给出了解题思路,我们只需要按照思路写代码就行了,例如:

从头开始扫描字符串,如果是数字,直接入数字栈,如果是符号则分情况讨论:

  1. 如果符号栈为空,则直接入栈
  2. 如果当前符号优先级小于等于符号栈顶优先级,则从数字栈取两个数字,从符号栈取一个符号,计算的结果弹入数字栈,然后把该符号入栈。
  3. 如果当前符号优先级大于符号栈顶符号优先级,则直接入栈。

当字符串扫描完毕后,则循环弹出计算,并将结果入数字栈。最后数字栈只剩一个数字,这就是表达式的结果。

很多人可能当时做出来了,但是对于为什么要这么做并不是很清楚,或者说难以记住这些计算步骤,如果下一次一样的题目但是没有提示的话也做不出来。
下面我就分享一下自己的心得,关于计算步骤。
主要是对于符号的观察。

1+2+3*4+5

对于上面的表达式,我们来逐一观察每个符号。首先是 + ,我们看到第一个+号的左右有两个操作数,但是此时我们不能急着计算,为什么?因为第一个操作数只属于第一个 +,无论如何他都会参与第一个 + 号的运算,但是第二个操作数可不止属于第一个+ 号,他还属于第二个符号,也就是 第二个 + ,所以我们这时候比较第一个符号和第二个符号的优先级,如果 1 > 2,说明1符号优先计算,这时候符号 1 左右的两个数都会优先参与它的计算,所以符号1就可以直接计算了,这就是为什么当前符号优先级小于等于符号栈顶优先级,则从数字栈取两个数字,从符号栈取一个符号,计算的结果弹入数字栈
这时候表达式变为

(1+2)+3*4+5

1+2的结果作为第二个+号的操作数之一,并且这个操作数只属于 + 号,但是+ 号右边的3 同时属于两个符号,所以我们接着看下一个符号 * ,乘号的优先级大于 + 号,所以3因该属于 乘号,所以+ 并不能计算,而乘号也只是拥有了一个操作数,还得继续看右边的数,只能入栈待定。这就是为什么如果当前符号优先级大于符号栈顶符号优先级,则直接入栈

你明白了吗?😉

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是使用实现简单计算器的 C 语言代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> // 定义结构体 typedef struct stack { int top; int capacity; int *array; } Stack; // 创建 Stack *createStack(int capacity) { Stack *stack = (Stack *) malloc(sizeof(Stack)); stack->top = -1; stack->capacity = capacity; stack->array = (int *) malloc(capacity * sizeof(int)); return stack; } // 判断是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 判断是否已满 int isFull(Stack *stack) { return stack->top == stack->capacity - 1; } // 入 void push(Stack *stack, int item) { if (isFull(stack)) { printf("已满,无法入\n"); return; } stack->array[++stack->top] = item; } // 出 int pop(Stack *stack) { if (isEmpty(stack)) { printf("为空,无法出\n"); return -1; } return stack->array[stack->top--]; } // 获取顶元素 int peek(Stack *stack) { if (isEmpty(stack)) { printf("为空\n"); return -1; } return stack->array[stack->top]; } // 计算两个数字的结果 int calculate(int num1, int num2, char op) { switch (op) { case '+': return num1 + num2; case '-': return num1 - num2; case '*': return num1 * num2; case '/': return num1 / num2; default: printf("非法操作符\n"); return 0; } } // 计算表达式的值 int evaluate(char *exp) { Stack *stack = createStack(strlen(exp)); int i, num = 0; for (i = 0; exp[i] != '\0'; i++) { if (isdigit(exp[i])) { num = num * 10 + (exp[i] - '0'); } else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { push(stack, num); num = 0; int num1 = pop(stack); int num2 = pop(stack); push(stack, calculate(num2, num1, exp[i])); } else if (exp[i] == ' ') { continue; } else { printf("非法字符\n"); return 0; } } return pop(stack); } // 测试代码 int main() { char exp[100]; printf("请输入表达式:\n"); fgets(exp, 100, stdin); printf("计算结果为:%d\n", evaluate(exp)); return 0; } ``` 这个简单计算器实现了四则运算,支持多位数字和空格,但不支持负数和括号。可以通过输入表达式来计算表达式的值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Little BigUs

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

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

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

打赏作者

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

抵扣说明:

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

余额充值