You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android计算器:如何对EditText输入的算术字符串执行运算?

实现计算器的算术表达式运算(ButtonEqual点击事件)

我来帮你搞定这个计算器的运算逻辑哈!首先得先把你现有代码里的小问题修正,再补上核心的运算实现——毕竟直接分割表达式还不够,四则运算可是有优先级的,得按规则来计算才行。

先修正你的表达式分割代码

你当前的分割逻辑有几个小bug:比如循环里的第二个if没做互斥判断,会导致同一字符触发两个逻辑;最后循环结束后没把最后一个数字加入buffer;还有str.charAt(j)应该是s1.charAt(j)。先把这部分改对:

buttonEqual.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
        String s1 = edt1.getText().toString(); 
        ArrayList<String> buffer = new ArrayList<>(); 
        String temp = ""; 

        // 遍历表达式,拆分数字和运算符
        for (int j = 0; j < s1.length(); j++) { 
            char c = s1.charAt(j);
            if (Character.isDigit(c) || c == '.') { 
                // 是数字或小数点,拼接到临时字符串
                temp += c; 
            } else if (c == '+' || c == '-' || c == '*' || c == '/') { 
                // 是运算符,先把之前的数字加入buffer
                if (!temp.isEmpty()) {
                    buffer.add(temp);
                    temp = "";
                }
                buffer.add(String.valueOf(c)); 
            }
        }
        // 循环结束后,把最后一个数字加入buffer
        if (!temp.isEmpty()) {
            buffer.add(temp);
        }

        // 接下来在这里实现运算逻辑
        double result = calculateExpression(buffer);
        edt1.setText(String.valueOf(result));
    }
});

核心:实现带优先级的四则运算

四则运算要先算乘除,后算加减,用栈来处理是比较经典的方案。我们可以写一个calculateExpression方法来处理拆分后的buffer:

private double calculateExpression(ArrayList<String> buffer) {
    Stack<Double> numStack = new Stack<>();
    Stack<Character> opStack = new Stack<>();

    // 定义运算符优先级
    Map<Character, Integer> priority = new HashMap<>();
    priority.put('+', 1);
    priority.put('-', 1);
    priority.put('*', 2);
    priority.put('/', 2);

    for (String item : buffer) {
        if (item.matches("\\d+\\.?\\d*")) { 
            // 是数字,转成double入栈
            numStack.push(Double.parseDouble(item));
        } else { 
            // 是运算符,处理优先级
            char op = item.charAt(0);
            while (!opStack.isEmpty() && priority.get(opStack.peek()) >= priority.get(op)) {
                // 栈顶运算符优先级更高,先计算
                double num2 = numStack.pop();
                double num1 = numStack.pop();
                char topOp = opStack.pop();
                double res = doOperation(num1, num2, topOp);
                numStack.push(res);
            }
            opStack.push(op);
        }
    }

    // 处理栈里剩下的运算符
    while (!opStack.isEmpty()) {
        double num2 = numStack.pop();
        double num1 = numStack.pop();
        char topOp = opStack.pop();
        double res = doOperation(num1, num2, topOp);
        numStack.push(res);
    }

    // 栈顶就是最终结果
    return numStack.pop();
}

// 执行单个运算
private double doOperation(double num1, double num2, char op) {
    switch (op) {
        case '+':
            return num1 + num2;
        case '-':
            return num1 - num2;
        case '*':
            return num1 * num2;
        case '/':
            if (num2 == 0) {
                // 处理除零错误,这里可以根据需求提示用户
                Toast.makeText(getApplicationContext(), "不能除以零", Toast.LENGTH_SHORT).show();
                return 0;
            }
            return num1 / num2;
        default:
            return 0;
    }
}

补充说明

  • 这个实现支持带小数点的数字运算,也处理了四则运算的优先级问题;
  • 我在除零的地方加了Toast提示,你可以根据自己的UI设计调整提示方式;
  • 如果需要支持负数(比如表达式开头是-5+3),还得在分割逻辑里加判断,比如开头是-或者运算符后面跟-的情况,把负数当成一个整体数字。

内容的提问来源于stack exchange,提问作者shyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:41:26