如何防止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
相关产品推荐
相关产品推荐

