使用栈实现计算四则运算

问题:
刚开始学JAVA时候写一个简易计算器是很容易的,比如说让用户输入一个表达式1+2=?,我们只需要判断给定两个int,一个String,变量就可以直接运算出来。
然而用户输入的是一个四则运算表达式呢?
比如:
2+3*2=?
3+2-1=?
2*(1+3)-6-(2/1)=?
3+(2*(1+2))=?
我们可以发现在这些算式中有两个问题:
1.算式长度不定
2.需要考虑优先级
需要计算出这样的算式我们需要做两件事:
1.将算式转化成后缀表达式
2.使用后缀表达式进行计算
这里先不用思考使用后缀表达式是怎么计算出来结果的,我们先来弄清楚怎么将算式转化成后缀表达式,我们来从第一个最简单的算式开始转化。

1+2的转化:

我们首先要创建一个栈(myStack)来储存算式中出现的运算符,再使用一个字符串(result)来保存结果。
然后我们开始从算式的开头逐个取出字符,如果字符是数字0-9,我们就直接加入result,如果取出的是运算符‘+-*/’就将符号压入符号栈中。
当所有字符都录入之后,将符号栈中的字符取出到result。
如图:
这里写图片描述
现在我们得到了一个后缀表达式“12+”。
那我们得到了一个后缀表达式后怎样计算结果呢?
解决方法也是使用一个储存整形值的栈,在这里我创建一个栈叫做numberStack,计算结果为result。
过程如图:
这里写图片描述
如果取出的字符为数字,则将数字压入栈中,如果取出的为运算符,则取出numberStack中了两个数字,进行运算符指定的规则运算。
第一步取出1,压入numberStack
第二步取出2,压入numberStack
第三步取出+,取出numberStack中的1和2,并存入num1和num2中。
第四部按照加法运算法则运算re = num1 + num2。
第五步后缀表达式到达结尾,返回结果result。
这个比较简单,那么再来求下一个

2+3*2=?

在这个算式中发现一个乘号,当然*号的优先级要大于+号,那么我们就需要考虑到比较优先级了。
和上面的例子相同我们需要对当前取出的字符和已经存在在字符栈中的字符做一个优先级的比较,如果优先级大于已存在字符栈中的最顶部的符号就不要着急将字符加到resultString当中,而等到输入结束再按照后进先出的顺序将运算符加入到resultString中。
如图:
这里写图片描述
那我们现在对后缀表达式进行运算:
这里写图片描述

如果当前字符优先级比字符栈中最顶部的字符小或者相等,那就应该直接将栈中的字符加入到result,然后再将当前字符压入字符栈中。
比如对于算式

3+2-1=?

如图:
这里写图片描述

计算:
这里写图片描述
在这次运算中出现了减法,在减法运算中需要考虑减数和被减数的顺序,我们只需要按照先出来的为减数,后出来的为被减数。
比如3-2的后缀表达式的为32-,可以看见被减数总是放在前面,这说明从栈中取出数字的时候被减数总是后取出来的那个数。(除数和被除数也遵循这个规律)

2*(1+3)-6-(2/1)=?

对于有括号的算式,我们就只需要等待把一对括号都录入之后再将符号加入resultString就可以了。
这里写图片描述
运算:
这里写图片描述

3+(2*(1+2))=?

这里写图片描述

运算:
这里写图片描述

好了,方法说完了上代码:

public class MyStack{
    private int top;
    private char[] menbers;
    private int maxSize;

    public MyStack(int value){
        this.maxSize = value;
        menbers = new char[maxSize];
        top = -1;
    }
    public void push(char menber) {
        if(!isFull()){
            menbers[++top] = menber;
        }else{
            System.out.println("Stack is full");
        }

    }

    public char pop() {
        if(!isEmpty()){
            return menbers[top--];
        }
        return '$';
    }

    public boolean isFull() {

        return top == maxSize-1;
    }

    public boolean isEmpty() {

        return top==-1;
    }

    public void disp(){
        for(int i = 0;i<=top;i++){
            System.out.print(menbers[i]+" ");
        }
    }

}
public class Entry{
    String result = "";
    MyStack symbolStack = new MyStack(20);
    public static void main(String[] args){
        String inputStr = "";

        try {
            Entry e = new Entry();
            while(!(inputStr = getString()).equals("end")){

                double result = e.start(inputStr);
            System.out.println("计算结果:"+result);
            }


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    //获得用户输入
    public static String getString() throws IOException{
        InputStreamReader input = new InputStreamReader(System.in);
        BufferedReader buf = new BufferedReader(input);
        String s = buf.readLine();
        return s;
    }
    //获得后缀表达式
    public String getPRString(String input){
        result = "";
        for(int i=0;i<input.length();i++){
            char ch = input.charAt(i);
            //System.out.print(ch + " ");
            switch(ch){
                case '/':
                case '*':
                    //判断优先级
                    prio(ch,2);
                    break;
                case '+':
                case '-':
                    prio(ch,1);
                    break;
                case '(':
                    symbolStack.push(ch);
                    break;
                case ')':
                    //括号内的表达式结束,将符号加入到结果中
                    while(!symbolStack.isEmpty()){
                        char chx = symbolStack.pop();
                        if(chx != '('){
                            result = result + chx;
                        }else{

                            break;
                        }
                    }
                    break;
                    //为数字的话直接录入
                default:
                    result = result + ch;
                    break;
            }



        }
        //整个表达式结束,清空储存的运算符
        while(!symbolStack.isEmpty()){
                result = result + symbolStack.pop();
            }
        System.out.println("后缀表达式:"+result);
        return result;
    }
    //比较优先级
    private void prio(char ch, int per) {

        while(!symbolStack.isEmpty()){
            int per2;
            //取出字符栈中的顶部的字符
            char theTop = symbolStack.pop();
            //如果为“(”那么就重新放回去,结束比较
            if(theTop == '('){
                symbolStack.push(theTop);
                break;
            }else{
                //将字符栈中的顶部的字符和正在录入的字符比较优先级
                if(theTop == '+' || theTop == '-'){
                    per2 = 1;
                }else{
                    per2 = 2;
                }
                //如果优先级大于栈中的顶部字符,那么就将当前的字符加入到字符栈中
                if(per > per2){
                    symbolStack.push(theTop);
                    break;
                }else{
                    //否则将顶部字符加入到结果中
                    result = result + theTop;
                    break;
                }
            }

        }
        symbolStack.push(ch);
    }

    public double start(String input){
        String prResult = "";
        //创建一个储存数字的栈
        NumberStack numberStack = new NumberStack(40);
        //获得后缀表达式
        prResult = getPRString(input);
        double result = 0;
        for(int i=0;i<prResult.length();i++){
            char ch = prResult.charAt(i);
            //如果是0到9,就将字符转化成数字存到栈中
            if(ch>='0'&&ch<='9'){
                double number = ch - '0';
                numberStack.push(number);
            }else{
                //如果是运算符,就取出栈中的最后进入的两个数字
                double num1 = numberStack.pop();
                double num2 = numberStack.pop();
                //开始运算
                switch(ch){
                case '-':
                    result = num2 - num1;
                    //将运算结果重新压入栈,替换运算前的两个数字
                    numberStack.push(result);
                    break;
                case '+':
                    result = num1 + num2;
                    numberStack.push(result);
                    break;
                case '*':
                    result = num1 * num2;
                    numberStack.push(result);
                    break;
                case '/':
                    result = num2 / num1;
                    numberStack.push(result);
                    break;


                }
                System.out.println(result);
            }

        }
        return result;
    }

}

如果您发现错误,请指出,共同进步:D

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用实现四则运算表达式的计算。具体步骤如下: 1. 定义一个结构,用于存放运算符和数字。 2. 读入表达式字符串,逐个字符进行处理。 3. 遇到数字字符时,将其转换为数字并压入中。 4. 遇到运算符时,从中弹出两个数字进行计算,并将结果压入中。 5. 最后中只剩下一个数字,即为表达式的计算结果。 下面是使用C语言实现的应用实现四则运算的示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 50 typedef struct { int top; int data[MAX_SIZE]; } Stack; void push(Stack *stack, int value) { if (stack->top == MAX_SIZE) { printf("Error: stack overflow\n"); exit(1); } stack->data[++stack->top] = value; } int pop(Stack *stack) { if (stack->top == -1) { printf("Error: stack underflow\n"); exit(1); } return stack->data[stack->top--]; } int calculate(char *expr) { Stack stack = {-1}; char *p = expr; while (*p != '\0') { if (*p >= '0' && *p <= '9') { int num = 0; while (*p >= '0' && *p <= '9') { num = num * 10 + (*p - '0'); p++; } push(&stack, num); } else if (*p == '+' || *p == '-' || *p == '*' || *p == '/') { int b = pop(&stack); int a = pop(&stack); switch (*p) { case '+': push(&stack, a + b); break; case '-': push(&stack, a - b); break; case '*': push(&stack, a * b); break; case '/': if (b == 0) { printf("Error: divide by zero\n"); exit(1); } push(&stack, a / b); break; } p++; } else { printf("Error: invalid character '%c'\n", *p); exit(1); } } if (stack.top != 0) { printf("Error: invalid expression\n"); exit(1); } return pop(&stack); } int main() { char expr[100]; printf("请输入四则运算表达式:"); scanf("%s", expr); int result = calculate(expr); printf("计算结果:%d\n", result); return 0; } ``` 在程序中,我们定义了一个结构 Stack,包含一个指向顶的 top 指针和一个数组 data 用于存放中的元素。push 函数实现元素的入,pop 函数实现元素的出。calculate 函数接收一个字符串类型的表达式,逐个字符进行处理,并使用计算表达式的值。 使用示例: ``` 请输入四则运算表达式:3+4*2/(1-5)^2 计算结果:3 ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值