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

如何防止Java递归方法中int length变量值随递归调用改变

问题背景

我正在学习Java,目前在递归相关问题上遇到了困难。
我需要通过递归方法判断一个数字是否为 Armstrong number(阿姆斯特朗数)。
我的实现代码如下:

public class ArmstrongChecker {

    public boolean isArmstrong(int number) {
        // check if the number is a negative number
        if (number < 0) {
            return false;
        }
        ArmstrongChecker armstrongChecker = new ArmstrongChecker();
        // find the length of the number
        int length = armstrongChecker.lengthChecker(number);
        // create a variable to store the sum of the digits of the number
        int sum = 0;
        // find the individual digits and raise to the power of the numbers of digits
        if (number != 0) {
            int digit = Math.floorMod(number, 10);
            int powerRaised = (int) Math.pow(digit, length);
            sum = sum + powerRaised;
            isArmstrong(number / 10);
        }
        return sum == number;
    }

    // method to check the length of the number
    public int lengthChecker(int number) {
        int length = String.valueOf(number).length();
        return length;
    }
}

具体问题:我应当如何操作,才能避免isArmstrong()方法中的 int length 变量在递归调用过程中值发生改变?

解决方案

你当前的代码不止length变量会随递归变化,还存在递归结果不累计的逻辑问题:

  • 每次递归调用isArmstrong()都会重新执行lengthChecker计算当前传入数字的长度,递归到高位时数字位数减少,计算出的length自然会变小
  • 方法内定义的sum是局部变量,每次递归都会生成独立的sum副本,上一层的幂计算结果不会累计,最终的相等判断逻辑也不成立

要固定length的值不在递归中改变,最通用的做法是拆分方法:把对外暴露的公共方法作为递归入口,只在第一次调用时计算一次数字总长度,再调用私有的递归辅助方法,把固定的长度值作为参数传入,递归全程复用这个传入值即可,不会重复计算。
修正后的可运行代码参考:

public class ArmstrongChecker {

    // 公共入口方法,仅在这里执行一次长度计算
    public boolean isArmstrong(int number) {
        if (number < 0) {
            return false;
        }
        // 只在入口处计算原数字的总长度,后续递归全程复用这个固定值
        int totalLength = lengthChecker(number);
        int powerSum = calculateSum(number, totalLength);
        return powerSum == number;
    }

    // 私有递归辅助方法,length作为固定参数传入,递归过程中不会修改
    private int calculateSum(int num, int fixedLength) {
        if (num == 0) {
            return 0;
        }
        int currentDigit = num % 10;
        return (int) Math.pow(currentDigit, fixedLength) + calculateSum(num / 10, fixedLength);
    }

    private int lengthChecker(int number) {
        return String.valueOf(number).length();
    }
}

如果不想拆分独立的私有方法,也可以通过重载isArmstrong方法实现:给重载版本加上length、累计和两个参数,入口方法调用重载版本时传入提前算好的固定length即可,核心逻辑和上述写法一致。
另外你原代码里每次递归都新建一个ArmstrongChecker实例的操作完全没有必要,直接调用当前实例的方法即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:01:14