任何人都可以帮我解决一些有效的算法来执行以下任务:
我有一个唯一行号的文件,每行有一个整数数组。
我需要检查每一行,以查看显示在不同行中的数组的值,并将它们放在一个组中。以下是它的外观示例:
行号;数据数组[...]
L1; [1,2,3,4,5]
L2; [2,3]
L3: [8,9]
L4: [6]
L5; [7]
L6; [5,6]
根据这些输入数据,我希望算法产生结果:
N组;行数组[...]
G1; [L1,L2,L4,L6]
G2; [ L3]
G3; [ L5]
P.S原始数据集占据了数亿行,并且可以包含近百万个数组元素......时间效率是一个问题。
由于
答案 0 :(得分:1)
我相信这相当于找到图表的连通组件:
这可以使用disjoint set data structure有效地完成,如下所示:
MakeSet(d)
代表每个数据值d(在您的示例中为1,2,3,4,5,6,7,8,9)join(A[0],A[i])
醇>
这将为每个连接的组件生成一个集合。然后,您可以通过第二次遍历行来生成输出数组:
set output to an array of empty lists
for each row r
A = array for row r
id = find(A[0])
output[id].append(r)
from collections import defaultdict
data=[[1,2,3,4,5],
[2,3],
[8,9],
[6],
[7],
[5,6]]
N=max(max(A) for A in data)
rank=[0]*(N+1)
parent=range(N+1)
def Find(x):
"""Find representative of connected component"""
if parent[x] != x:
parent[x] = Find(parent[x])
return parent[x]
def Union(x,y):
"""Merge sets containing elements x and y"""
x = Find(x)
y = Find(y)
if x == y:
return
if rank[x]<rank[y]:
parent[x] = y
elif rank[x]>rank[y]:
parent[y] = x
else:
parent[y] = x
rank[x] += 1
# First join all data
for row,A in enumerate(data):
for x in A:
Union(A[0],x)
# Then place rows into sets
D=defaultdict(list)
for row,A in enumerate(data):
D[Find(A[0])].append(row+1)
# Then display output
for i,L in enumerate(D.values()):
print i+1,L
运行此代码会输出输出:
1 [3]
2 [1, 2, 4, 6]
3 [5]