【问题标题】:Euler Project - Greatest prime factor computational power can't handle my script [closed]Euler Project - 最大的素数计算能力无法处理我的脚本 [关闭]
【发布时间】:2014-07-05 21:20:24
【问题描述】:

我有这段工作代码,但是当我对其应用大数字时它就会挂起。 本质上,我正在研究最大的主要因素。 由于我试图找到的素数的大小,它的计算成本很高(欧拉项目) 我的小笔记本电脑无法处理这个问题。

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

/* My code is done on the assumption i do not get garbage in. */
bool isPrime(long long int num){
    int val;
    for (val = 3; val < num; val=val+2) { //Offset at 3 start then +2 to half calculations required such that 
                                      //I don't waste processing power on even numbers.
                                      //I'd like to know if i could also skip the calculation by avoiding multiples of 3
    if (num % val == 0) { 
        return false; //Exit this function when remainder is 0, such that number is divisible by 
        }  
    }
    return true;
}

int main(void)
{
    long long int num_in=600851475143; //This does not work.
    // long long int num_in=13195; //This works
    long long i;
    // The biggest factor = total/2. 
    // However what is the biggest prime factor?

    for (i = num_in/2; i > 1; i=i-2)
    {
        if (num_in % i == 0) //Confirm this is a factor
        {
            if (isPrime(i))  //Confirm that factor is prime
            {
                printf("%lld \n", i );
                return 0; // Exit program

            }
        }
    }
    printf("This has been a failure \n");
    return 0;
}

【问题讨论】:

  • 您有什么问题吗?还是您寻求的具体帮助?
  • 我可以建议你改变你的算法吗?继续除以找到的最小因子,直到你不能再除:) 你会看到你的程序提高了数百万倍的速度。
  • 欧拉计划问题的重点是想出比蛮力算法更有效的方法。它与“你的小笔记本电脑”无关。当使用更高效的算法时,您的笔记本电脑有足够的计算能力来解决问题,而世界上最大的超级计算机在使用效率不够高的算法时却没有足够的计算能力。
  • @YePhIcK 好建议,但应注意速度的提高取决于输入。在素数输入的情况下,它不会改变
  • 另一个问题可能是您的long long,尽管是 64 位的,但被分配了一个 int 类型的常量,这在 sizeof(int) != sizeof(long long) 时会造成各种破坏。查看600851475143,应该是600851475143LL。否则,在最好的情况下,您将得到一个模数 2^(CHAR_BIT*sizeof(int) - 1),在 32 位 int 的情况下为 1703537351。它与你的算法无关,但值得注意的是你的算法何时起作用。

标签: c for-loop prime-factoring


【解决方案1】:

要确定一个数是否为素数,只需检查它是否具有高达该数平方根的除数(数学证明几乎是微不足道的)。当您检查一个数字是否是一个因素时,类似的逻辑也成立 - 因此无需检查该数字的平方根。这些是计算中最重要的减速因素。

【讨论】:

    【解决方案2】:

    在评论中跟进我的建议 - 重新设计算法以减少数字运算量:

    #include <iostream>
    #include <math.h>
    
    int main()
    {
        const long long int num_in = 600851475143;
        long long int curr = num_in;
        while(true){
            const long long int sr = static_cast<long long int>(sqrt(static_cast<long double>(curr)));
            long long int i = 2;
            for(; i <= sr; ++i){
                if(curr % i == 0){
                    curr /= i;  // get rid of this prime
                    break;      // and start the loop again
                }
            }
            if(i >= sr){
                // couldn't divide anymore
                break;
            }
        }
        std::cout << num_in << "'s largestprime factor is: " << curr << std::endl;
    }
    

    上面的代码输出:

    600851475143's largestprime factor is: 6857
    

    请注意,您可以使用古老的 C 样式类型转换来缩短其中包含 sqrt() 调用的长行,如下所示:

    const long long int sr = (long long int)sqrt((long double)curr);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2012-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多