冰雹序列,递归,缺少 1 个案例
Hailstone Sequence, recursive, missing the 1 case
我有以下冰雹序列代码,它适用于所有数字,除了 1 的序列:
public class Recursion {
public static void main(String[] args) {
hailstone(16); // prints 16 8 4 2 1
hailstone(1); //prints just 1 instead of 1 4 2 1
}
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 1) {
System.out.print(str);
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
}
如何在递归方法和无效的情况下绕过这种特殊情况?
不允许我使用任何类型的循环。
最后一个小提示供您参考(我很惊讶地看到代码中的所有静态内容)。
进入正题。你说:
- 您不能更改签名
- 你必须使用递归(不允许循环)
定义一个静态布尔值并为达到数字 1 的情况添加条件。
冰雹序列中的最后一个序列是无限模式。特殊情况是因为您需要程序在某个时候停止。在这里,我只是使用一个布尔值在第一次达到数字 1 后打印一次图案。我希望代码是自我解释的。
public class Recursion {
private static boolean reached = false;
public static void main(String[] args) {
//hailstone(16); // prints 16 8 4 2 1
hailstone(1); //prints just 1 instead of 1 4 2 1
}
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 1 && reached) {
System.out.print(str);
} else if (seed == 1 && !reached) {
System.out.print(str + " ");
reached = true;
hailstone((3 * seed) + 1);
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
}
注意:在 Java 中,编写大量静态代码通常不是一个好习惯 members/methods。我相信它可以设计得更好。我不想讨论这个,因为我不想混淆,我想专注于这个问题。
例如,按照我所做的方式对其进行编码有一个缺点。只需尝试随后调用 hailstone(16)
和 hailstone(1)
,您就会明白我的意思;这是因为布尔值已经从第一个序列计算中设置。您需要再次将其重置为 false。有更好的设计方法...
1
是你递归的出口点,这就是为什么你不能让它也表现得像一个入口点。
如果你改变出口点怎么办?将 2
设置为预退出点:
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 2) {
System.out.print(str + " 1");
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
public static void main(String[] args) {
hailstone(16);
System.out.println();
hailstone(15);
System.out.println();
hailstone(1);
System.out.println();
}
将打印:
16 8 4 2 1
15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
1 4 2 1
我有以下冰雹序列代码,它适用于所有数字,除了 1 的序列:
public class Recursion {
public static void main(String[] args) {
hailstone(16); // prints 16 8 4 2 1
hailstone(1); //prints just 1 instead of 1 4 2 1
}
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 1) {
System.out.print(str);
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
}
如何在递归方法和无效的情况下绕过这种特殊情况?
不允许我使用任何类型的循环。
最后一个小提示供您参考(我很惊讶地看到代码中的所有静态内容)。
进入正题。你说:
- 您不能更改签名
- 你必须使用递归(不允许循环)
定义一个静态布尔值并为达到数字 1 的情况添加条件。
冰雹序列中的最后一个序列是无限模式。特殊情况是因为您需要程序在某个时候停止。在这里,我只是使用一个布尔值在第一次达到数字 1 后打印一次图案。我希望代码是自我解释的。
public class Recursion {
private static boolean reached = false;
public static void main(String[] args) {
//hailstone(16); // prints 16 8 4 2 1
hailstone(1); //prints just 1 instead of 1 4 2 1
}
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 1 && reached) {
System.out.print(str);
} else if (seed == 1 && !reached) {
System.out.print(str + " ");
reached = true;
hailstone((3 * seed) + 1);
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
}
注意:在 Java 中,编写大量静态代码通常不是一个好习惯 members/methods。我相信它可以设计得更好。我不想讨论这个,因为我不想混淆,我想专注于这个问题。
例如,按照我所做的方式对其进行编码有一个缺点。只需尝试随后调用 hailstone(16)
和 hailstone(1)
,您就会明白我的意思;这是因为布尔值已经从第一个序列计算中设置。您需要再次将其重置为 false。有更好的设计方法...
1
是你递归的出口点,这就是为什么你不能让它也表现得像一个入口点。
如果你改变出口点怎么办?将 2
设置为预退出点:
public static void hailstone(int seed) {
String str = "" + seed;
if (seed == 2) {
System.out.print(str + " 1");
} else {
if (seed % 2 == 0) {
System.out.print(str + " ");
hailstone(seed / 2);
} else {
System.out.print(str + " ");
hailstone((3 * seed) + 1);
}
}
}
public static void main(String[] args) {
hailstone(16);
System.out.println();
hailstone(15);
System.out.println();
hailstone(1);
System.out.println();
}
将打印:
16 8 4 2 1
15 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
1 4 2 1