【问题标题】:Project Euler #3 C++ Program CrashProject Euler #3 C++ 程序崩溃
【发布时间】:2018-06-15 20:26:10
【问题描述】:

问题说明:

13195 的质因数是 5、7、13 和 29。

600851475143 的最大质因数是多少?

这是我在 C++ 中的尝试

#include <bits/stdc++.h>
using namespace std;

void ProblemThree(long long int n) {
    bool prime[n];
    memset(prime, true, sizeof(prime));
    for (int i = 2; i * i < n; i++) {
        if (prime[i]) {
            if (n % i == 0) {
                printf("d", i);
                for (int k = 2 * i; k <= n; k += i) {
                    prime[k] = false;
                }
            }
        }
    }
}

int main() {
    ProblemThree(600851475143);
}

程序意外崩溃,编译器未显示任何错误。为什么会这样?我该如何阻止它发生?

【问题讨论】:

  • bool prime[n]; 将是一个“可变长度数组”。 VLA不是标准的 C++ 特性(尽管有些编译器很遗憾地接受它们作为扩展 - 使用 gcc,将 -Wvla -Werror 添加到编译器命令行以确保您不会意外使用它们)。如果您想要 C++ 中的动态数组,请使用 std::vector
  • #include &lt;bits/stdc++.h&gt; 也不是标准 C++。
  • using namespace std; - 虽然合法,但只是一个真的坏习惯。
  • 当我们这样做的时候,printf("d", i); 是完全错误的。

标签: c++


【解决方案1】:

它崩溃是因为您尝试分配的数组太大。由于您有一个数字要测试,因此您不需要存储中间结果,您可以继续计算该数字的素数分解并取最大因子。

您可以使用以下算法计算 O(1) 空间的解:

long long  maxPrimeFactor(long long n)
{
    long long maxPrimeFactor = 1;
    while (n%2 == 0)
    {
        n = n/2;
        maxPrimeFactor = 2;
    }

    // n must be odd at this point.  So we can skip 
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i+2)
    {
        while (n%i == 0)
        {
            maxPrimeFactor = max(maxPrimeFactor, i);
            n = n/i;
        }
    }

    if (n > 2){
        maxPrimeFactor = max(maxPrimeFactor, n);
    }

    return maxPrimeFactor;
}

注意:代码未经测试,但它应该给出想法并且仍然接近工作。

【讨论】:

  • 听起来很有可能。您不需要大小为 n 的数组。正如循环条件所建议的那样,您最多需要一个大小为 sqrt(n) 的数组。但是您也不需要存储所有这些。
  • @JamesFaix 确实,这可以在 O(1) 空间复杂度内解决。
猜你喜欢
  • 1970-01-01
  • 2010-09-17
  • 1970-01-01
  • 2016-03-14
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多