找到最大的主要因素 - 代码的复杂性

Find Largest Prime Factor - Complexity of Code

本文关键字:代码 复杂性      更新时间:2023-10-16

我在编码网站上尝试了一个代码,以找到一个数字的最大质量因素,并且超过了上一次测试案例的时间限制,因为他们可能正在使用大质量数字。您能帮我降低以下代码的复杂性吗?

int main()
{
    long n;
    long int lar, fact;
    long int sqroot;
    int flag;
    cin >> n;
    lar=2, fact=2;
    sqroot = sqrt(n);
    flag = 0;
    while(n>1)
    {
        if((fact > sqroot) && (flag == 0))         //Checking only upto Square Root
        {
            cout << n << endl;
            break;
        }
        if(n%fact == 0)
        {
            flag = 1;
            lar = fact;
            while(n%fact == 0)
                n = n/fact;
        }
        fact++;
    }
    if(flag == 1)         //Don't display if loop fact reached squareroot value
        cout << lar << endl;
}

在这里,我还照顾了循环检查直到平方根值。不过,如何进一步降低其复杂性?

您可以通过提供用于fact初始值的第一个n个量子的硬编码列表来加快(如果不降低复杂性),因为使用fact的复合值是浪费时间。之后,避免fact的明显复合值(例如偶数数字)。

您可以通过跳过大于2的数字来减少测试数量,如果发现较小的因素,则可以更快地停止。这是一个更简单,更快的版本:

int main() {
    unsigned long long n, lar, fact, sqroot;
    cin >> n;
    lar = 0;
    while (n && n % 2 == 0) {
        lar = 2;
        n /= 2;
    }
    fact = 3;
    sqroot = sqrt(n);
    while (fact <= sqroot) {
        if (n % fact == 0) {
            lar = fact;
            do { n /= fact; } while (n % fact == 0);
            sqroot = sqrt(n);
        }
        fact += 2;
    }
    if (lar < n)
        lar = n;
    cout << lar << endl;
    return 0;
}

我不确定输入号可能会变大,使用较大的unsigned long long进行这些计算会比long更远。使用预先计算的素数将有助于进一步,但没有很大的因素。

我获得的越好的结果是使用下面的功能(lpf5())。它基于使用公式6K 1,6K-1个性化素数的primality()函数(下图)。所有素数> = 5可以用k> 0的表格p=k*6+1p=k*6-1表达(但并非所有具有此类表格的数字都是素数)。开发这些公式,我们可以看到以下序列:

k=1 5,7
k=2 11,13
k=3 17,19
k=4 23,25*
k=5 29,31
.
.
.
k=10 59,61
k=11 65*,67
k=12 71,73
...
5,7,11,13,17,19,23,25,29,31,...,59,61,65,67,71,73,...

我们观察到术语之间的差异为2和4。也可以使用简单的数学获得这样的结果。很明显,k*6 1和k*6-1之间的差异是2。很容易注意到k*6 1和(k 1)*6-1是4。

当x为prime时函数 primality(x)返回x(或0-注意),并且当x不是prime时发生第一个除数。

我认为您可能会获得更好的结果,将primality()函数内部插入lpf5()功能。

我还尝试在原始函数内插入一些带有一些素数(从1到383的素数 - 指定公式的前128个结果的素数),但速度差是无法欣赏的。

在这里代码:

#include <stdio.h>
#include <math.h>
typedef  long long unsigned int uint64;
uint64 lpf5(uint64 x);
uint64 primality(uint64 x);
uint64 lpf5(uint64 x)
{
    uint64 x_=x;
    while ( (x_=primality(x))!=x)
        x=x/x_;
    return x;
}
uint64 primality(uint64 x)
{
    uint64 div=7,f=2,q;
    if (x<4 || x==5)
        return x;
    if (!(x&1))
        return 2;
    if (!(x%3))
        return 3;
    if (!(x%5))
        return 5;
    q=sqrt(x);
    while(div<=q) {
        if (!(x%div)) {
            return div;
        }
        f=6-f;
        div+=f;
    }
    return x;
}
int main(void) {
    uint64 x,k;
    do {
        printf("Input long int: ");
        if (scanf("%llu",&x)<1)
            break;
        printf("Largest Prime Factor: %llun",lpf5(x));
    } while(x!=0);
    return 0;
}