获得这个的一种方法是自然数(1,.., n )我们将每个数据分解并查看它们是否有任何重复的素数因子,但这需要花费大量时间大 n 。那么有没有更好的方法从1,.., n 获得无方形数字?
答案 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之间的任何数字上进行迭代。
答案 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