Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 一个数中不小于另一个数的除数的个数_Performance_Algorithm_Math_Prime Factoring - Fatal编程技术网

Performance 一个数中不小于另一个数的除数的个数

Performance 一个数中不小于另一个数的除数的个数,performance,algorithm,math,prime-factoring,Performance,Algorithm,Math,Prime Factoring,有没有什么有效的方法可以找到一个数(比如n)的除数不小于另一个数(比如m)的除数。 n最多可为10^12。 我考虑过筛子算法&然后找到除数的数目。 我的方法检查从m到n的平方根的所有数字。 但我认为还有另一种方法(有效)可以做到这一点。如果你知道素数因子,就很容易找到一个数的除数;只要考虑所有因素的多重性的所有可能组合 对于小到10^12的n,试用除法应该是一种足够快的因式分解方法,因为您只需检查最大为10^6的潜在因素 编辑:增加关于“所有可能的组合”和按试算法进行保理的讨论 考虑数字2450

有没有什么有效的方法可以找到一个数(比如n)的除数不小于另一个数(比如m)的除数。 n最多可为10^12。 我考虑过筛子算法&然后找到除数的数目。 我的方法检查从m到n的平方根的所有数字。
但我认为还有另一种方法(有效)可以做到这一点。

如果你知道素数因子,就很容易找到一个数的除数;只要考虑所有因素的多重性的所有可能组合

对于小到10^12的n,试用除法应该是一种足够快的因式分解方法,因为您只需检查最大为10^6的潜在因素

编辑:增加关于“所有可能的组合”和按试算法进行保理的讨论

考虑数字24505=5*13*13*29。要枚举其因子,请取所有因子的多重数的所有可能组合:

5^0 * 13^0 * 29^0 = 1
5^0 * 13^0 * 29^1 = 29
5^0 * 13^1 * 29^0 = 13
5^0 * 13^1 * 29^1 = 377
5^0 * 13^2 * 29^0 = 169
5^0 * 13^2 * 29^1 = 4901
5^1 * 13^0 * 29^0 = 5
5^1 * 13^0 * 29^1 = 145
5^1 * 13^1 * 29^0 = 65
5^1 * 13^1 * 29^1 = 1885
5^1 * 13^2 * 29^0 = 845
5^1 * 13^2 * 29^1 = 24505
也不难通过审判庭计算出一个数字。这是算法,你可以把它翻译成你最喜欢的语言;对于10^12以下的数字,速度足够快:

function factors(n)
    f = 2
    while f * f <= n
        if n % f == 0
            output f
            n = n / f
        else
            f = f + 1
    output n
功能因子(n)
f=2

虽然f*f这取决于应用程序,但如果性能是这样一个问题,我会使用预先生成的哈希表。显然,存储在内存中的10^12个条目可能是不切实际的(或者至少是不可取的),所以我会对第k个素数进行除法测试,只为那些不能被前k个素数整除的数生成哈希表条目

例如,尽管写得粗糙且未经测试,但这应该给您一个想法:

int   number   = 23456789;
int   primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 0};
int   pfactors = 0;
int*  prime = primes;
float temp;

// check until we reach the end of the array (0)
while (prime)
{
    // divide by prime and check if result is integer
    temp = (float)number/*prime;
    if (temp == floor(temp))
    {
        // if so, increment count of prime factors and loop (same prime again!)
        pfactors++;
        number = (int)temp;
    }
    else
    {
        // else try the next prime
        prime++;
    }
}

// finally, rely on hash table magic
pfactors += pregenerated_hash[number];

下面是一个示例程序,用于计算大于m的n的除数。如果有c除数,则largeDivs()代码在时间O(c)中运行。largeDivs()也以n表示为带因数的数字开始,nset是一个形式(p_i,k_i)对的列表,这样n=乘积{p_i**k_i for i in 1..h}。程序后显示了一些示例输出。check()例程用于演示largeDivs()生成正确的结果。对于较小的m值,check()需要很长时间

def largeDivs(n, nset, m):
    p, k = nset[-1]
    dd = 0
    if len(nset) > 1:
        nn, mm = n / p**k, m
        for i in range(k+1):
            dd += largeDivs(nn, nset[:-1], mm)
            mm = (mm + p-1)/p
    else:
        c, v = k+1, 1
        while v<m and c>0:
            c, v = c-1, v*p
        return c
    return dd

def check (n,m,s):
    if m<1:
        return s
    c = 0
    for i in range(m,n+1):
        if (n%i)==0:
            c += 1
    return c


tset = [(2,3),(3,2),(11,1),(17,1),(23,2)]
n = s = 1
for i in tset:
    s *= 1+i[1]
    n *= i[0]**i[1]
print 'n=',n, '  s=',s
m=0
for i in range(8):
    print 'm:', m, '\t', largeDivs(n, tset, m), '  Check:',check(n,m,s)
    m = 10*m + 5

但是检查所有可能的组合非常耗时!不是吗?不可被第一个
k
素数整除的数字的比例变小得相当慢。对于小于20的素数,剩下约17.1%,对于小于100的素数,仍然约12%,对于小于1000的素数,大约8.1%,10000:6.1%。即使丢弃所有可被任何小于100万的素数整除的数字,也需要一个相当大的哈希表。这将使素数介于100万和10^12之间。有37607912018个素数不超过10^12,因此哈希表的条目数将超过3.76*10^10。@DanielFisher-非常有用,谢谢。我将在以后的扫描中删除此答案。不要删除此答案。消极证据也是证据。:)
n= 7122456   s= 144
m: 0    144   Check: 144
m: 5    140   Check: 140
m: 55   124   Check: 124
m: 555  95   Check: 95
m: 5555     61   Check: 61
m: 55555    28   Check: 28
m: 555555   9   Check: 9
m: 5555555  1   Check: 1