包含在其中的集合数量的简明解决方案

时间:2011-01-13 23:02:14

标签: c# algorithm performance pattern-matching

假设我有一个简短的字符串列表,可以包含重复项:<“A”,“A”,“B”,“B”,“C”,“C”,“D”,“E “,”F“>

然后假设我有一些其他字符串列表,可能是也可能不是原始列表的子集。我需要知道:

  1. 第二组是否“覆盖”第一组(例如,第一组中的每个项目是否也包含在第二组中)?
  2. 如果1为真,则重新创建第一组需要多少第二组实例?
  3. 所以,在这种情况下,如果我的第二组是列表:<“A”,“B”,“C”,“D”,“E”,“F”>,我会得到TRUE, 2.

    如果是列表:<“A”,“B”,“C”>,我会得到FALSE。

    如果我的第一个是<“A”,“A”,“A”,“A”,“B”,“B”,“B”,“C”,“C”>:

    • 第二个是<“A”,“B”,“C”>:返回TRUE和4.
    • 第二个是<“A”,“A”,“B”,“C”>:返回TRUE和3.

    我知道使用嵌套循环可以在N x M时间内轻松完成。但我正在寻找简洁和/或优化的(最好是基于Linq的)解决方案。我玩 Linq.Except ,但问题是它只返回不同的元素,因此在比较包含重复项的字符串列表时没用。

    任何人都有什么独特的想法吗?

1 个答案:

答案 0 :(得分:5)

  

第二组是否“覆盖”第一组(例如,第一组中的每个项目是否也包含在第二组中)?

// Assuming that the elements are comparable (strings are);
// if not, need to implement your own IComparer<T>
var doesCover = !original.Except(secondList).Any();
  

重建第一组需要多少个第二组实例?

var instancesRequired = secondList.GroupBy(e => e)
    .Max(gr => (original.Count(e => e.Equals(gr.Key))
               + gr.Count() - 1) / gr.Count());

警告:如果originalsecondList都为空,那么doesCover将为true,但instancesRequired的计算将引发异常。可能因此需要专门检查空列表。