我可以按照维基百科上列出的三元树算法生成所有互质对: https://en.wikipedia.org/wiki/Coprime_integers
快速:
int longestSequence(int a[], int n ,int* begin)
{
int oldlength=1,length=1,i,maxvalue=0;
for(i=0; i<n; i++)
{
if(a[i+1]==a[i])
{
length++;
if(length>oldlength)
{
oldlength=length;
*begin=i;
}
}
else
{
oldlength=length;
length=1;
}
然而,每对产生的空间使用的空间将增加三倍(并且说打印,或者不保留在内存中)。
这可能是haskell的解决方案: Generating sorted list of all possible coprimes
但是我在python中寻找一些东西,它没有懒惰的评估或无限的列表。
答案 0 :(得分:5)
这使用了对数空间,也许它足够好了?它是线性时间(使用O(k)时间产生第一对k)。
def coprimes():
yield (2, 1)
yield (3, 1)
for m, n in coprimes():
yield (2*m - n, m)
yield (2*m + n, m)
yield (m + 2*n, n)
你可以在David Eppstein的这些文章中阅读更多关于这种自递归生成器的信息:
显示前20对的演示:
>>> pairs = coprimes()
>>> for _ in range(20):
print(next(pairs))
(2, 1)
(3, 1)
(3, 2)
(5, 2)
(4, 1)
(5, 3)
(7, 3)
(5, 1)
(4, 3)
(8, 3)
(7, 2)
(8, 5)
(12, 5)
(9, 2)
(7, 4)
(9, 4)
(6, 1)
(7, 5)
(13, 5)
(11, 3)
演示显示第十亿对,这使得我的PC大约需要4分钟,而Python进程的内存使用率保持在任何Python进程至少占用我的9.5 MB基线。
>>> from itertools import islice
>>> next(islice(coprimes(), 10**9-1, None))
(175577, 63087)
答案 1 :(得分:1)
接受的Haskell解决方案的Python版本
def find_coprimes():
l = 1
while True:
i = 2
while i < l-i:
if gcd(i, l-i) == 1:
yield i, l-i
i += 1
l += 1
只获得几个:
iterator = find_coprimes()
for i in range(10):
print(next(iterator))
输出:
(2, 3)
(2, 5)
(3, 4)
(3, 5)
(2, 7)
(4, 5)
(3, 7)
(2, 9)
(3, 8)
(4, 7)
答案 2 :(得分:1)
该问题未说明生成的互质对的条件(例如,是特定范围内的数字之一吗?)。不过,我发现以下两个示例很有趣(都需要恒定的空间)。
首先考虑Farey sequence,这是Python 3中的示例:
a, b, c, d = 0, 1, 1, n
while c <= n:
k = (n + b) // d
a, b, c, d = c, d, k * c - a, k * d - b
print(a, b)
它将枚举具有1 <= a <= b <= n的所有互质对a,b。
第二个例子有点古怪,使用基于Calkin–Wilf tree的想法,您可以无限制地枚举所有互素对。好吧,至少在数学上,实际上,您仅受能够在内存中表示的数字数量的限制。无论如何,这是一个Python 3示例:
a, b = 0, 1
while True:
a, b = b, 2*(a//b) * b - a + b
print(a, b)
如果您想找到一些满足某些性质的有理数的示例,但是却不知道界限,这可能会很方便。当然,您可以尝试所有可能的自然数对,但这会直接生成互素对。