我正在学习Java,遇到了一个递归问题。
我需要使用递归方法来检查一个数字是否是Armstrong数。
我的代码:
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更改其值。
当您在发布的代码中不更改它的值时,您可以将该变量标记为常量。这样,如果您试图分配一个新值,编译器可能会出错。
final int length = armstrongChecker.lengthChecker(number);
正如我在评论中所说的,您的解决方案存在以下问题:
- 递归调用
isArmstrong()
的结果被忽略 - 不需要生成
ArmstrongChecker
的新实例。而且这种方法根本不需要创建对象,它可以实现为static
- 检查该数字是否为Armstrong数可以归结为计算其Armstrong和,如果您使用递归仅实现该部分,则解决方案将更干净
它可能看起来像这样:
public static boolean isArmstrong(int number) {
if (number < 0) return false;
if (number < 10) return true;
return number == getArmstrongSum(number, String.valueOf(number).length());
}
public static int getArmstrongSum(int number, int power) {
if (number == 0) {
return 0;
}
return (int) Math.pow(number % 10, power) + getArmstrongSum(number / 10, power);
}
main()
public static void main(String[] args) {
System.out.println(isArmstrong(370)); // true
System.out.println(isArmstrong(12)); // false
System.out.println(isArmstrong(54)); // false
System.out.println(isArmstrong(153)); // true
}
输出:
true
false
false
true
整个递归需要获得一次长度,因此最干净的方法是将数字和长度都传递到递归中。实现这一点的一个简单方法是使用一个方法作为API的公共面,另一个方法进行递归。
public class ArmstrongChecker {
public boolean isArmstrong(int number) {
if (number < 0) {
return false;
}
int length = lengthChecker(number);
int sum = armstrongSum(number, length);
return sum == number;
}
private int armstrongSum(int number, int length) {
int sum = 0;
if (number != 0) {
int digit = Math.floorMod(number, 10);
int powerRaised = (int) Math.pow(digit, length);
sum += powerRaised;
sum += armstrongSum(number / 10, length);
}
return sum;
}
public int lengthChecker(int number) {
int length = String.valueOf(number).length();
return length;
}
}
这在递归中很常见,算法递归部分的参数与API客户端必须传入的参数略有不同(通常更多)。每次递归调用中的数字都会变化,其中传递number / 10
,但始终传递相同的length
。
请注意,递归armstrongSum
使用递归调用的返回值,并且当您已经在类的实例方法中时,不需要创建ArmstrongChecker
的另一个实例。