分解质因数

前言

数学苦手来计算 1+1 的答案了,以下内容可能引起某些dalao的不适或血压升高,建议快速跳过,纯当乐子。

疑问

对于任何一个数N,其因子可以两两配对,我们枚举小因子。易知小因子 >=sqrt(N),大因子 >=sqrt(N),因此考虑从 2 到 sqrt(N) 枚举小因子。同时应该考虑大因子,因为并不是所有质因子都 <=sqrt(N) 的!

但是网上的试除法是这样说的:

扫描 2 到 sqrt(N) 中的每个数,如果 x 能整除 N,从 N 中除掉所有质因子 x

这样扫描出来的x确实全部都是质数,但是并没有考虑大因子,因此我觉得这是有问题的(显然是因为我太弱了~_~|||)

比如 17*2*2*3=204,sqrt(204)=14.2828568570587

考虑什么样的大因子不会被枚举到。首先这个大因子应该 >=sqrt(N),也就是说没有比它更大的质因子了,而且这样没有被枚举到的大质因子只能有一个

根据这个,似乎可以改进我的算法:

v[ ] 为质数表 is[ ]为合数标记

原算法 divide1 需要遍历到 N 的最大质因子

 

inline void divide1(int x)
{
    if(!is[x])
    {
        printf("%d",x);
        return;
    }

    int pos=1;
    while(x!=1)
    {
        if(x%v[pos]==0)
        {
            while(x%v[pos]==0)
            {
                printf("%d ",v[pos]);
                x/=v[pos];
            }
        }
        ++pos;
    }
}

 

 

现算法 divide2 需要遍历到 min(floor(sqrt(N)),N的最大质因数))

 

inline void divide2(int x)
{
    if(!is[x])
    {
        printf("%d",x);
        return;
    }

    int pos=1;
    int li=sqrt(x);

    while(x!=1&&v[pos]<=li)
    {
        if(x%v[pos]==0)
        {
            while(x%v[pos]==0)
            {
                printf("%d ",v[pos]);
                x/=v[pos];
            }
        }
        ++pos;
    }

    if(x!=1)
    {
        printf("%d ",x);
    }
}

 

 

结果

运行时间对比

分解99999

算法1:0.0010000

算法2:0.0000000

分解30840

算法1:0.0030000

算法2:0.0010000

可见对于部分特殊数据,优化还是有用的。

结语

加快了自己分解质因数的时间效率,已经为之后学习更优的算法提供了动力。

题外话

我知道这种东西谁都会。所以请包容弱小的我。

posted @ 2021-07-28 12:21  imfkwk  阅读(191)  评论(0编辑  收藏  举报