这个用于测试 Collat​​z 猜想的脚本有什么问题?

这个用于测试 Collat​​z 猜想的脚本有什么问题?

我想制作一个测试科拉茨猜想的脚本。更具体地说,目标是制作一个脚本,允许我输入一个非 1 的正整数,并在 Collat​​z 算法完成时打印出最终的数字,我预计该数字将是 1。

取任意正整数n。如果 n 是偶数,则将 n 除以 2,得到 n / 2。如果 n 是奇数,则将 n 乘以 3,然后加 1,得到 3n + 1。无限重复该过程。该猜想指出,无论你从哪个数字开始,最终都会达到 1。

这是我的尝试——

echo "Enter in a positive integer greater than 1"
read n
let "r=$n%2"
if [ $n -le 1 ]
then
echo "Error: you must enter in a positive integer greater than 1"
exit
fi
while [ $n -ne 1 ]
do
    if [ $r == 0 ]
    then
          let "n=$n/2"
          echo $n
    fi

    if [ $r -ne 0 ]
    then
          let "n=3*$n + 1"
          echo $n
    fi
done

echo $n

当我输入 2 时,我得到 1,这是所需的结果。然而,当我读入 3 的值时,我得到一个无限循环,如下所示:

931947686741790850
2795843060225372551
8387529180676117654
6715843468318801347
1700786331246852426
5102358993740557279
-3139667092487879778
9027742796245912283

.
.
.

等等。

我的确切问题是:我的代码有什么问题吗?是什么导致它打印大量数字?

答案1

这:

let "r=$n%2"
...
while [ $n -ne 1 ]
do
    if [ $r == 0 ]
    ...
done

r您只在循环之外分配一次。

在大多数编程语言中,类似的赋值y = f(x)意味着“获取 的当前值xf(x)使用它进行计算,然后将结果复制到y”。这与数学解释不同,数学解释更像是“从现在到永远,y应始终相等f(x)”。请注意,在n您的代码中,它甚至不能像这样工作:您正在修改它的值并依赖它在循环的不同迭代中不同。

r因此,无论从初始数字获得什么值,它都会保留在整个循环中,并且您可以为循环的每次迭代重复相同的操作。当然,三倍的那个只会跑到巨大的数字上,然后开始溢出。

解决方法很简单,将赋值移到r循环内部,以便每次n更改时重新计算。

您还存在未加引号的变量扩展的常见问题,但它们不是您的问题。

相关内容