You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何质因数分解大数?欧拉计划第3题代码问题及优化咨询

你的代码问题分析与大数字质因数分解方案

首先,你的代码处理小数字正常,但大数字无输出的核心原因是效率极低,导致程序需要运行极长时间(甚至永远跑不完),而非真的没有输出。我们来拆解具体问题,再给出改进方案:

代码存在的关键问题

  • 质数判断效率太差:内层循环for(long long int c = 2 ; c < i ; c++)要遍历到i-1才能确定i是否为质数。实际上,判断一个数是否为质数,只需要检查到它的平方根(sqrt(i))就够了——如果i有大于平方根的因数,那对应的另一个因数必然小于平方根,早就被检查到了。
  • 外层遍历范围过于庞大:外层循环要从2遍历到a-1,比如欧拉计划第3题的目标数600851475143,这个循环要执行几百亿次,完全不可能在合理时间内完成。
  • 质因数查找逻辑冗余:你先找所有小于a的质数,再判断是否能整除a,这完全是绕远路——质因数分解的正确思路应该是不断用最小的因数去整除目标数,逐步缩小目标数,最后剩下的就是最大的质因数。

改进后的高效代码

我们重新设计逻辑,直接通过分解质因数的方式找最大质因数,代码如下:

#include <iostream>
#include <cmath>
using namespace std;

int main() {
    long long int input_num;
    cout << "Please enter a number...!" << endl;
    cin >> input_num;

    long long int largest_prime = 0;

    // 先处理所有能被2整除的情况
    while (input_num % 2 == 0) {
        largest_prime = 2;
        input_num /= 2;
    }

    // 现在input_num是奇数,从3开始遍历,步长设为2,只检查奇数
    for (long long int i = 3; i <= sqrt(input_num); i += 2) {
        // 当i是input_num的因数时,不断除以i,直到不能整除为止
        while (input_num % i == 0) {
            largest_prime = i;
            input_num /= i;
        }
    }

    // 如果最后剩下的input_num大于2,说明它本身就是一个质数(也就是最大的质因数)
    if (input_num > 2) {
        largest_prime = input_num;
    }

    cout << "The biggest prime is = " << largest_prime << endl;
    return 0;
}

这段代码处理欧拉计划第3题的600851475143,能瞬间给出结果6857。

大数字质因数分解的进阶思路

如果要处理更大的数字(比如超过64位整数范围的数),可以结合以下方法:

  • 预生成小质数表:用埃氏筛法生成1e6以内的质数,先拿这些小质数试除目标数,能快速分解掉大部分小因数。
  • Pollard's Rho算法:这是一种高效的大数分解算法,通过随机化策略快速找到合数的一个非平凡因数,然后递归分解这些因数,直到得到所有质因数。
  • Miller-Rabin素性测试:和Pollard's Rho配合使用,快速判断一个大数是否为质数,避免对质数进行无效的分解操作。

内容的提问来源于stack exchange,提问作者Dasty Dustleg

火山引擎 最新活动