多少共同项目

时间:2016-01-28 19:24:08

标签: algorithm data-structures

假设我们有这些信息:

更新

Group A - Item 1, Item 2, Item 3
Group B - Item 1, Item 3
Group C - Item 3, Item 4

我想知道哪些群组包含最常见的内容:

输出:

Group A - (Item 1 and Item 3)
Group B - (Item 1 and Item 3)

你会使用什么算法?

2 个答案:

答案 0 :(得分:0)

首先,您必须表示数据集:

data[A] = {1,2,3}
data[B] = {1,3}
data[C] = {3,4}

最好使用数字,这样你就可以使用for循环,计数器等。所以:

data[0] = {1,2,3}
data[1] = {1,3}
data[2] = {3,4}

然后我会有另一个数据结构,其中包含你所拥有的组之间有多少匹配的计数器,所以例如匹配[A] [B] = 2,匹配[A] [C] = 1,依此类推。这是您需要计算的数据结构。如果您这样做,那么您的问题将减少到在该数据结构中找到最大值。

for i = 0; i < 3; i++
   for item in data[i] 
      for j = 0; j < 3; j++
         //optimize a little bit (match[A][A] doesn't make sense)
         if j == i
            next
         if item in data[j]
            matches[i][j]++

当然,您可以对此进行更优化。例如,我们知道匹配[A] [B]将等于匹配[B] [A],你可以跳过这些迭代。

答案 1 :(得分:0)

因此,给定一个组及其包含项目的列表,您希望输出与另一个组具有相同,最大项目数的所有组的标识。

让我们得到一个群组和项目列表:

group_items = (
    ('Group A', ('Item 1', 'Item 2', 'Item 3')),
    ('Group B', ('Item 1', 'Item 3')),
    ('Group C', ('Item 3', 'Item 4')),
    )

然后让我们为每个组存储 max#items shared 值,这样我们就可以在最后收集所有匹配的组。我们还会跟踪 max of maxes ,因为我们可以(而不是返回并重新计算它)。

max_shared = {item[0]:0 for item in group_items}
num_groups = len(group_items)
group_sets = {}
max_max = 0

现在我们要将每个组与其他组进行比较,但我们可以忽略某些比较。正如@Perroloco所提到的,将A组与A组进行比较是没有用的,并且计算相交(A,B)与计算相交(B,A)是对称的,因此我们的范围可以从0到N,然后从i + 1到N,而不是0..N交叉0..N。

我正在使用set数据类型,需要花费 来构建。所以我缓存了这些集合,因为我们没有修改成员资格,只计算交集的成员资格。

值得指出的是,虽然交点(A,B)==交叉点(B,A),但A的MAX与B的MAX不同。因此,有单独的比较内部最大和最大外部

for i in range(num_groups):
    outer_name, outer_mem = group_items[i]

    if outer_name not in group_sets:
        group_sets[outer_name] = set(outer_mem)

    outer_set = group_sets[outer_name]
    outer_max = max_shared[outer_name]

    for j in range(i+1, num_groups):
        inner_name, inner_mem = group_items[j]

        if inner_name not in group_sets:
            group_sets[inner_name] = set(inner_mem)

        inner_set = group_sets[inner_name]

        ni = len(outer_set.intersection(inner_set))

        if ni > outer_max:
            outer_max = max_shared[outer_name] = ni

        if ni > max_max:
            max_max = ni

        if ni > max_shared[inner_name]:
            max_shared[inner_name] = ni

print("Overall max # of shared items:", max_max)

results = [grp for grp,mx in max_shared.items() if mx == max_max]

print("Groups with that many shared items:", results)