- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我必须将一个数字列表分成两组,这样一组中没有一个数字的因数也是第二组中任何数字的因数。我认为我们然后只需要找出组,使得每组中数字乘积的 GCD 为 1。例如-
如果我们有列表 2,3,4,5,6,7,9 可能的组是 -
(2,3,4,6,9)(5,7)(2,3,4,5,6,9)(7)(2,3,4,6,7,9)(5)
我最初想做的是——
从前面的例子来看,算法看起来像这样 -
我认为此算法可行,但它是解决此问题的一种非常糟糕的方法。我可以对素数进行硬编码直到一个很大的数字,然后找到最接近我的最大数字的素数,这可能会使它更快,但如果元素的数量是 10E6 或更多的数量级,它仍然涉及太多的除法。我在想也许有更好的方法来解决这个问题。也许我遗漏了一些数学公式,或者一些可以减少迭代次数的小逻辑。
我的问题是关于算法的,所以伪代码也可以,我不需要完成的代码。但是,我对 Python、Fortran、C、BASH 和 Octave 很满意,所以用这些语言回答也会有所帮助,但正如我所说,语言不是这里的重点。
而且我想我可能不知道一些可能会使我的问题变得更好的术语,因此也感谢您提供任何改写方面的帮助。
最佳答案
tl;dr:使用素数筛选法获取素数列表,使用不相交集存储和组合组
您走在正确的轨道上。您可以使用 Sieve of Erasthones得到素数列表,你只需要 ~O(n log n)
时间和内存来分解素数,这还不错。
让我们稍微重构问题的后半部分:
现在您的问题是找到两个不相交的节点组。将这些组存储在 disjoint set 中.
您的示例的略短版本,包含元素 [2,3,4,5,6]
。让我们跟踪子集列中的每组节点,并遍历上面的数组。
| iteration | subsets | subset1 | description |
|-----------|-----------------|---------|-------------------------------------------------------------------------------------------------------------------------|
| start | [] | n/a | |
| 1 | [] | {2} | add a new subset, 2 |
| 2 | [{2}] | {3} | 3 shares no common factors with 2, so create a new subset 2 |
| 3 | [{2},{3}] | {4} | 4 shares a common factor with 2, but not with 3, so merge it with {2} |
| 4 | [{2,4},{3}] | {5} | 5 shares no common factors with 2,3 or 4, so create a new subset |
| 5 | [{2,4},{3},{5}] | {6} | 6 shares a common factor with {2,4}, so merge it into that. it also shares a common factor with {3}, so merge that too |
| 6 | [{2,4,3,6},{5}] | | done |
从具有标准属性 make_set
、union
和 find
方法的不相交集开始,如 Wikipedia 中所述。
get_prime_factors
对其进行扩充,返回该子集元素的主要因子的 Python 集
,以提高空间效率,只有父节点应包含此属性def get_prime_factors(x):
return Find(x)._prime_factors
union
以返回对新创建的集合的引用并跟踪素数因子(集合交集)def union(x, y):
# use Wikpidia's code
# ...
# add this:
xRoot._prime_factors |= yRoot._prime_factors
return xRoot
get_subsets()
,这是一种迭代子集的方法。天真的方法是遍历原始数组并在每个数组上运行 find
。不太天真的方法是用另一组来跟踪 parent ,但这种选择不会影响最坏情况下的运行时间。disjoint_set = AugmentedDisjointSet([])
elems = [2,3,6,5,4]
for new_number in elems:
subset1 = disjoint_set.make_set(new_number)
for subset2 in disjoint_set.get_subsets():
if (subset1.get_prime_factors() & subset2.get_prime_factors()): # merge if the subsets share a common factor
subset1 = disjoint_set.union(subset1, subset2)
# show result. this may give between 1 (all numbers share a common factor)
# and infinite subsets (all numbers are relatively prime)
# for your example, this will return something like {2,3,4,6,9}, {5}, {7}
# you can group them however you'd like to.
print('result': disjoint_set.get_subsets())
最坏情况在 O(n^2*a(n))
时间内运行,其中 a(n)
是反阿克曼函数(即非常小),如果每个元素都是互质的,并且 O(n)
空间。
关于python - 将数字列表分成两组,使得一组中的数字与另一组中的数字没有任何共同因素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57514180/
所以,我有一个类似于 this one 的用例,但我觉得有一些额外的细节值得提出一个新问题。 ( related questions ,供引用) 我正在编写一个实现 a cycle 的数据结构.基本设
我正在使用 Django 编写一个社交网络应用程序,需要实现类似于 Facebook“Mutual Friends”概念的功能。我有一个像这样的简单模型: class Friend(models.Mo
我有一个 iOS 应用程序,用户可以在其中使用 Facebook 登录并授予 user_friends 权限。从 Graph API 2.0 开始,Facebook 声称你无法获取两个人之间所有的共同
我想知道将来对我来说最简单的方法是什么,可以使查询既有效又不那么复杂。 我应该像这样保存双向关系吗 from_id=1, to_id=2from_id=2, to_id=1 或者只创建一个唯一的行 f
我是一名优秀的程序员,十分优秀!