Android计算器:如何对EditText输入的算术字符串执行运算?
我来帮你搞定这个计算器的运算逻辑哈!首先得先把你现有代码里的小问题修正,再补上核心的运算实现——毕竟直接分割表达式还不够,四则运算可是有优先级的,得按规则来计算才行。
先修正你的表达式分割代码
你当前的分割逻辑有几个小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
相关产品推荐
相关产品推荐

