获取无方形数字列表

时间:2011-03-15 14:32:37

标签: algorithm number-theory

获得这个的一种方法是自然数(1,.., n )我们将每个数据分解并查看它们是否有任何重复的素数因子,但这需要花费大量时间大 n 。那么有没有更好的方法从1,.., n 获得无方形数字?

9 个答案:

答案 0 :(得分:10)

您可以使用Eratosthenes Sieve的修改版本:

拿一个bool数组1 .. n ;

预先计算所有小于n的正方形;那是O(sqrt(N));

对于每个方块及其倍数,使bool数组条目为false ...

答案 1 :(得分:7)

最让人想到的是将素数列为n并最多选择其中一个。这对大n来说并不容易(例如here's one algorithm),但我不确定这个问题是不是。

答案 2 :(得分:7)

来自http://mathworld.wolfram.com/Squarefree.html

  

没有已知的多项式时间   识别squarefree的算法   整数或计算   squarefree整数的一部分。在   事实上,这个问题可能并不容易   比整数的一般问题   分解(显然,如果是   整数可以完全考虑,   如果它包含no,则为squarefree   重复的因素)。这个问题是   一个重要的未解决的问题   数论因为计算   代数的整数环   数字字段可以简化为计算   整数的squarefree部分   (Lenstra 1992,Pohst和Zassenhaus   1997年)。

答案 3 :(得分:2)

一种方法是使用筛子,类似于Eratosthenes'。

@Will_Ness在Python中编写了一个“快速”主筛,如下所示。

from itertools import count
                                         # ideone.com/
def postponed_sieve():                   # postponed sieve, by Will Ness      
    yield 2; yield 3; yield 5; yield 7;  # original code David Eppstein, 
    sieve = {}                           # Alex Martelli, ActiveState Recipe 2002
    ps = postponed_sieve()               # a separate base Primes Supply:
    p = next(ps) and next(ps)            # (3) a Prime to add to dict
    q = p*p                              # (9) its sQuare 
    for c in count(9,2):                 # the Candidate
        if c in sieve:               # c's a multiple of some base prime
            s = sieve.pop(c)         #     i.e. a composite ; or
        elif c < q:  
            yield c                  # a prime
            continue              
        else:   # (c==q):            # or the next base prime's square:
            s=count(q+2*p,2*p)       #    (9+6, by 6 : 15,21,27,33,...)
            p=next(ps)               #    (5)
            q=p*p                    #    (25)
        for m in s:                  # the next multiple 
            if m not in sieve:       # no duplicates
                 break
         sieve[m] = s                # original test entry: ideone.com/WFv4f

稍微努力,这可以用来弹出无方形整数,使用postponed_sieve()作为尽可能少的方格筛分的基础:

def squarefree():                   # modified sieve of Will Ness
    yield 1; yield 2; yield 3;      # original code David Eppstein,
    sieve = {}                      # Alex Martelli, ActiveState Recipe 2002
    ps = postponed_sieve()          # a base Primes Supply:
    p = next(ps)                    # (2) 
    q = p*p                         # (4)
    for c in count(4):              # the Candidate
        if c in sieve:              # c's a multiple of some base square
            s = sieve.pop(c)        #     i.e. not square-free ; or
        elif c < q:  
            yield c                 # square-free
            continue              
        else:   # (c==q):           # or the next base prime's square:
            s=count(2*q,q)          #    (4+4, by 4 : 8,12,16,20...)
            p=next(ps)              #    (3)
            q=p*p                   #    (9)
        for m in s:                 # the next multiple 
            if m not in sieve:      # no duplicates
                break
        sieve[m] = s

这很快,在我的笔记本电脑上推出了大约.8秒的第一百万。

不出所料,这表明这实际上与筛选质数相同,但密度更大。

答案 4 :(得分:0)

您应该查看sieve of Atkin。当然,这会消除所有非素数(不仅仅是完美的正方形),因此它可能比你需要的更多。

答案 5 :(得分:0)

谷歌搜索了一下我发现这个page解释了J程序。算法是复杂语法的一部分,它允许检查数字是否是无方形的:

  • 生成一个完美的方形PS列表,

  • 取你的数字N除以 列表中的数字PS

  • 如果列表中只有1个整数, 然后N是无方形的

您可以使用首选语言实现该算法,并在1到n之间的任何数字上进行迭代。

答案 6 :(得分:0)

http://www.marmet.org/louis/sqfgap/

查看“基本算法:Eratosthenes的筛子”部分,这是Armen建议的。下一节是“算法的改进”。

此外,FWIW,Moebius函数和无平方数都是相关的。

答案 7 :(得分:0)

我找到了一种更好的算法来计算区间内有多少平方自由数,例如[n,m]。我们可以得到小于sqrt(m)的素数,然后我们应该减去那些素数平方的倍数,然后加上每两个素数乘以小于m的倍数,然后减去树,然后加上四......最后我们会得到答案。当然它运行在O(sqrt(m))

答案 8 :(得分:0)

import math
def squarefree(n):
    t=round(math.sqrt(n))
    if n<2:
       return True
    if t*t==n:
       return False
    if t<=2:
       return True
    for i in range(2,t):
        if n%(i*i)==0:
           return False
        else:
           return True