我的代码最长Collat​​z序列有什么问题?

时间:2020-04-11 12:24:20

标签: c algorithm brute-force collatz

我一直在尝试解决这个问题:

为正数的集合定义了以下迭代序列 整数:

n→n / 2(n为偶数)
n→3n + 1(n为奇数)

使用上面的规则并从13开始,我们生成以下内容 顺序:
13→40→20→10→5→16→8→4→2→1

可以看到,这个顺序(从13开始到1结束) 包含10个字词。尽管尚未得到证实(Collat​​z 问题),可以认为所有起始数字都以1结尾。

哪个起始编号小于一百万,会产生最长的链条?

注意:链条一旦开始,条款就可以超过一个 百万。

并且我实现了以下代码,但这似乎并没有给我正确的答案。它计算910107作为给出最长链的起始数字,但是答案应该是837799。这有什么问题?

#include<stdio.h>

int main(void)
{

    int count=1;
    int last_count =0;
    int num=13;
    int temp;
    int Largest_Num=0;
    for(int i=num;i<1000000;i++)
    {
        temp = i;
        while(temp>1)
        {
            if(temp % 2 == 0)
            {
                temp/=2;
            }
            else
            {
                temp =(3*temp)+1;
            }
            count++;   

        }

        if(last_count < count)
        {
            last_count = count;
            Largest_Num = i;
        }

        count =1;
    }
    printf("%d\n",last_count);
    printf("%d",Largest_Num);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

我得到910107作为给出最长链的起始号码,但答案应该是837799

int 太短,无法管理 temp 所需的大量数字,但您溢出了

这意味着您的 int 使用32位,在这种情况下 int 仅使用31位作为正数,而您需要32

您可以将 temp 声明为 unsigned int (比起 int 多1位,因为您只需要正数),或使用 long (如果您使用的是64位),或者 long long 以确保至少有64位

答案 1 :(得分:0)

正如@bruno在他的回答中观察到的那样,您超出了系统的int数据类型的容量。问题甚至暗示这是您可能会遇到的问题,当它说:

注意:链条启动后,允许的条款就可以超过一百万。

以上多少?从问题上还不清楚,所以“如何确定哪种数据类型足够?”这个问题应该立即浮现在脑海。当然,前面的问题“我应该选择哪种数据类型?”是至少应该一直得到真正关注的时刻。

假设您对要计算的序列没有先验知识,并且在一般情况下没有明确的方法确定其元素的可靠上限,确定哪种数据类型将需要实际执行(尝试)计算并观察溢出。或者,您可以选择一个您认为足够的数据类型,然后进行验证以证明它实际上是足够的。如果不是,那么请使用其他数据类型再试一次。

在这种情况下,防止溢出很容易。唯一需要监视的变量是temp,仅当您计算temp =(3*temp)+1时,其值才会增加。您知道类型int的最大值是(INT_MAX),并且很容易用代数方法确定计算不超过temp的{​​{1}}的最大值:它是INT_MAX。因此,您可以执行以下操作:

(INT_MAX - 1) / 3

如果最终导致断言失败(使用类型#include <assert.h> #define TEMP_BOUND ((INT_MAX - 1) / 3) // ... if(temp % 2 == 0) { temp /= 2; } else { assert(temp <= TEMP_BOUND); temp = (3 * temp) + 1; } 时将失败),则可以使用支持更大最大值的数据类型重试;否则,请重新启动。只需确保随后针对新数据类型适当地更新int宏即可。

我还应该观察到,还有一种选择可以使用任意精度的数据类型执行计算,例如可以从各种第三方库(例如GMP)中获得。但是,这将慢得多,并且代码也将更加复杂,因此,对于这种情况,我建议使用上面概述的反复试验方法,至少要达到您确定没有内置数据类型足以解决问题。