几组交叉的算法模型

时间:2013-03-07 06:25:48

标签: algorithm set complexity-theory intersection

我的问题是,我们如何应用5~7套交集。假设每组都有一组元素。请帮我创建一个算法,以及这个过程的复杂性。

3 个答案:

答案 0 :(得分:2)

假设集合的元素可以被散列,并且你有一些像词典一样的Hash-Key工具(或者可以创建你自己的,这并不难):

List<Set<element-type>> sets;    \\your list of sets to intersect

int size = SUM{List[*].Count};  \\ size for the hash
Dictionary<element-type,int> Tally = New Dictionary<element-type,int>(size);

// Add all elements to the Tally hash
foreach set in sets
{
    foreach e in set
    {
        if (Tally.Exists(e))
            Tally[e]++;
        else
            Tally.Add(e,1);
    }
}

//Now, find the Tally entries that match the number of sets
foreach kvp in Tally.KeyValuePairs
{
    If (kvp.Value == sets.Count)
        // add the Key to output list/set
        Output.Add(kvp.Key);
}

这具有运行时复杂度O(n)其中“n”是所有集合中元素的数量。

答案 1 :(得分:1)

直接的方法:

I = S_1;
For each set s in S_2 ... S_N:
    For each element ei in I:
      if ei not in s
        remove ei from I
      endif
    endfor
endfor

如果每组具有m个元素并且有N个集合,则复杂度为m ^ 2xN。如果集合已经排序,那么你可以使用二进制搜索的mlog(m)N,或者通过在排序的情况下使两个迭代器前进来获得O(mN)。

答案 2 :(得分:1)

我现在假设这些集合被表示为列表,并且它们开始是未排序的。

(编辑为符合@perreal的符号)

在N个集合中总共有m * N个项目,可以将这些集合连接成一个列表(m * N个操作),对列表进行排序(m * N log m * N个操作),然后运行排序列表,保留列表中具有正好N个副本的任何项目(另一个m * N个操作),给出总计(我认为)m * N(2 + log m * N)操作的任何情况。

相比之下,假设每个集合具有相同数量的项目m,我认为如果集合全部相同,@ perreal的解决方案将是最多m ^ 2 * N个操作。对于大的m * N值,这将需要比我的算法的m * N(2 + log m * N)操作更多的操作。但是,在最好的情况下,@ perreal的解决方案只需要2m * N次操作(如果测试的第一和第二组没有交集)。

@ perreal的解决方案对于交叉点较小的情况也需要较少的操作,如果按照大小的递增顺序比较集合,则S_1是最小的集合。

如果集合作为排序列表开始,两个解决方案都会更快,因为不需要我的算法的初始排序,@ perreal的算法可以决定一个元素不在集合中而不必搜索整套。