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

Java命令行计算器sqrt运算符实现报错,求解决方案

Java命令行计算器sqrt处理异常修复方案

错误根源

  1. 变量名冲突:处理sqrt的point变量与后续解析数字的point变量重名,导致解析阶段的point初始值被错误设置为处理完sqrt后的位置,而转换后的input长度短于原输入,触发substring越界(如报错中的Range [6, 1))。
  2. sqrt处理逻辑缺陷:仅提取sqrt后的单个字符,无法处理多位数(如sqrt 16会被错误转换为1^0.5),且硬编码索引p+5易因格式变化出错。
  3. 重复添加数字:循环结束后额外执行nums.add(Float.parseFloat(input.substring(point))),导致重复添加最后一个数字,甚至在point超出input长度时触发异常。
  4. 未处理乘法符号x:用户示例中的6x2^3-3未被转换为标准乘法符号*,会导致解析失败。

修复后的完整代码

import java.util.ArrayList;
import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        int counter = 0;
        String[] operators = {"^", "/", "*", "+", "-"};
        Scanner myScan = new Scanner(System.in);
        String inputs = myScan.nextLine();
        ArrayList<Float> nums = new ArrayList<>();
        ArrayList<String> ops = new ArrayList<>();

        // 先处理乘法符号x为*,兼容用户示例写法
        inputs = inputs.replace('x', '*');
        
        float currentNum;
        // 改名避免与后面解析数字的point变量冲突
        int sqrtPoint = 0;
        String input = "";

        // 修复sqrt处理逻辑:提取完整数字,支持多位数和小数
        for (int p = 0; p <= inputs.length() - 4; p++) {
            if (inputs.startsWith("sqrt", p)) {
                // 添加sqrt之前的内容
                input += inputs.substring(sqrtPoint, p);
                // 找到sqrt后面数字的起始位置(跳过空格)
                int numStart = p + 4;
                // 找到数字的结束位置
                int numEnd = numStart;
                while (numEnd < inputs.length() && (Character.isDigit(inputs.charAt(numEnd)) || inputs.charAt(numEnd) == '.')) {
                    numEnd++;
                }
                // 提取完整数字并转换为^0.5形式
                String num = inputs.substring(numStart, numEnd);
                input += num + "^0.5";
                // 更新sqrtPoint到数字结束位置
                sqrtPoint = numEnd;
                // 跳过已处理的数字部分,避免重复遍历
                p = numEnd - 1;
            }
        }
        // 添加剩余未处理的内容
        input += inputs.substring(sqrtPoint);
        System.out.println("转换后表达式:" + input);

        // 解析数字和运算符,使用独立的point变量
        int point = 0;
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            // 判断是否为运算符,或处理最后一个字符的情况
            if ((!Character.isDigit(c) && c != '.') || i == input.length() - 1) {
                try {
                    // 处理最后一个字符时,截取到字符串末尾
                    int endIndex = (i == input.length() - 1) ? input.length() : i;
                    currentNum = Float.parseFloat(input.substring(point, endIndex));
                    nums.add(currentNum);
                    point = i + 1;
                } catch (Exception e) {
                    System.out.println("无效数字:" + input.substring(point, i));
                    return;
                }
                // 如果不是最后一个字符,添加对应的运算符
                if (i != input.length() - 1) {
                    for (String op : operators) {
                        if (input.startsWith(op, i)) {
                            ops.add(op);
                            // 预留多字符运算符的处理逻辑
                            i += op.length() - 1;
                            break;
                        }
                    }
                }
            }
        }

        // 按照运算优先级计算表达式
        for (String operator : operators) {
            for (int j = 0; j < ops.size(); j++) {
                String op = ops.get(j);
                if (op.equals(operator)) {
                    float num1 = nums.get(j);
                    float num2 = nums.get(j + 1);
                    float result = switch (op) {
                        case "^" -> (float) Math.pow(num1, num2);
                        case "/" -> num1 / num2;
                        case "*" -> num1 * num2;
                        case "+" -> num1 + num2;
                        case "-" -> num1 - num2;
                        default -> 0;
                    };

                    nums.set(j, result);
                    nums.remove(j + 1);
                    ops.remove(j);
                    j--;
                }
            }
        }

        float answer = nums.get(0);
        System.out.println("计算结果:" + answer);
        myScan.close();
    }
}

关键修改说明

  • 重命名point变量为sqrtPoint,彻底避免变量冲突问题。
  • 重构sqrt处理逻辑:通过循环提取完整数字,支持多位数和小数,替换易出错的硬编码索引。
  • 移除重复添加数字的冗余代码,避免重复计算或越界。
  • 添加x到*的转换逻辑,兼容用户示例中的乘法写法。
  • 优化数字解析逻辑,统一处理普通字符和最后一个字符的截取,减少异常触发点。

内容的提问来源于stack exchange,提问作者The-Senate_V

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:55:12