我正在做一个exercise并编写了以下代码:
while (n != 1) {
if (n % 2 == 0) n = n / 2;
if (n % 2 == 1) n = 3 * n + 1;
++count;
}
但它导致循环无限运行。诀窍是删除第二个if并输入else语句而不是第二个if。
我不明白为什么这会对我的例子产生任何影响。 n不断减少到1,并且在一次循环迭代期间,两个if语句都不能同时执行。
显然,if-else版本在逻辑上更有意义,因为如果数字不均匀,那么它必须是奇数。但是我没有看到我错过了两个ifs的边缘情况。
答案 0 :(得分:2)
您的代码存在的问题是您在第一个n
中重新分配if
,然后影响第二个if
子句。如果您使用else
,则不会发生这种情况,因为每个循环会触发一个且只有一个分支。
快速修复:
while (n != 1) {
if (n % 2 == 0) {
n = n / 2;
} else {
n = 3 * n + 1;
}
++count;
}
由于n % 2
的唯一其他可能结果是1,因此您不需要任何复杂的逻辑。这实际上是唯一的另一种可能性。
答案 1 :(得分:2)
让我们回溯你的代码,看看会发生什么。
如果n == 1
,您的循环将退出。
这意味着内部代码需要将1
分配给n
才能退出。
我们内部有两个作业n = n / 2
和n = 3 * n + 1
,并指明何时应该发生这些作业。
因此,我们假设第一个语句最终将1
分配给n
。要实现这一点,n % 2 == 0
必须为真,所以我们假设循环开始时n
等于2
。
if (n % 2 == 0)
将启动,找出结果为true
,从而执行if
语句n = n / 2
中的语句。这会将1
分配给n
。
然后下一个if语句出现了。请注意,n
现在等于1
。 if (n % 2 == 1)
现在最终会得到true
的结果,从而执行。
然后n = 3 * n + 1
将执行,这将评估为n = 3 * 1 + 1
或n = 4
。
因此n
最终为4。
唯一让此循环退出的方法是获得以下情况:
0
分配给n
1
分配给n
获取第一个if语句以执行和将1
分配给n
的唯一方法是n == 1
是否开始,而不是let label = UILabel()
label.font = UIFont(name: "Menlo", size: 20)
label.textColor = .white
label.text = self.navigationItem.title
self.navigationItem.titleView = label
触发if-statement。
因此,这个循环无法完成,因为它的标准不会发生。