2013-11-14 34 views
2

我有几个阵列,如:查找元素的最常见的组合在多个阵列

var arr1 = new[] { "A", "B", "C", "D" }; 
var arr2 = new[] { "A", "D" }; 
var arr3 = new[] { "A", "B", }; 
var arr4 = new[] { "C", "D" }; 
var arr5 = new[] { "B", "C", "D" }; 
var arr6 = new[] { "B", "A", }; 

...等

我怎样才能得到最常见的元素组合在所有这些数组?

在这种情况下,它是A和B,因为它们出现在arr1,arr3和arr6以及C和D中,因为它们出现在数组arr1,arr4和arr5中。

只要提及元素可以在任何类型的集合,即。也在ArrayLists中。

UPDATE uuhhh,我是不够清楚...... 两个元件在阵列中的最常见的组合。这就是我试图用示例展示的内容,但在我的问题中没有提到。

对不起 : - ((

+0

定义最常见的。前N个计数,至少存在Y次还是什么? –

+1

''A“本身对于数组1,2,3和6是相同的。”B“也一样,它出现在四个而不是三个数组中。为什么他们需要结合考虑? – dasblinkenlight

+0

你的问题不完整。你询问最常见的元素,但你的例子是关于元素对的。是否只考虑了一对元素?一个元素必须存在多少个实例才能被视为“最常见”的候选者?单个元素“A”在4个数组中。 –

回答

3

如果你确定每个数组只出现一次,你可以将它们连接在一起,计数,例如:

var arrs = new[] { arr1, arr2, arr3, arr4, arr5, arr6 }; 
var intermediate = arrs.SelectMany(a => a) 
         .GroupBy(x => x) 
         .Select(g => new { g.Key, Count = g.Count() }) 
         .OrderByDescending(x => x.Count); 
var maxCount = intermediate.First().Count; 
var results = intermediate.TakeWhile(x => x.Count == maxCount); 

或者如果你喜欢查询语法,这将是:

var arrs = new[] { arr1, arr2, arr3, arr4, arr5, arr6 }; 
var intermediate = 
    from a in arrs.SelectMany(a => a) 
    group a by a into g 
    orderby g.Count() descending 
    select new { g.Key, Count = g.Count() }; 
var maxCount = intermediate.First().Count; 
var results = intermediate.TakeWhile(x => x.Count == maxCount); 

结果集将有3款产品:

Key, Count 
"A", 4 
"B", 4 
"D", 4 

更新

鉴于你更新的问题,就像这样d工作:

var items = arrs.SelectMany(a => a).Distinct(); 
var pairs = 
    from a in items 
    from b in items 
    where a.CompareTo(b) < 0 
    select new { a, b }; 
var results = 
    (from arr in arrs 
    from p in pairs 
    where arr.Contains(p.a) && arr.Contains(p.b) 
    group arr by p into g 
    orderby g.Count() descending 
    select g.Key) 
    .First(); 

这里的逻辑是:

  1. 首先发现任何阵列
  2. 然后找出每对项目的搜索
  3. 让每一个对所有不同的项目,分组通过列表列出哪些阵列包含该对
  4. 按组排列数量排序包含每对,降序
  5. 返回第一对
+1

即使项目出现多次,您也可以使用'SelectMany(a => a.Distinct())'来解决问题。 [我怀疑这是什么OP后,虽然](http://stackoverflow.com/questions/19981046/find-most-common-elements-in-several-arrays#comment29745297_19981046),因为如果他想要你的东西查询给出,他会谈论出现四次的“A”,“B”和“D”,而不是“A”,“B”出现三次。 – dasblinkenlight

1

使用字典将一个元素存储为一个索引,并且出现计数作为值迭代每个列表并计数出现

0
var arr1 = new[] { "A", "B", "C", "D" }; 
var arr2 = new[] { "A", "D" }; 
var arr3 = new[] { "A", "B", }; 
var arr4 = new[] { "C", "D" }; 
var arr5 = new[] { "B", "C", "D" }; 
var arr6 = new[] { "B", "A", }; 

var results = new List<IEnumerable<string>>() { arr1, arr2, arr3, arr4, arr5, arr6 } 
           .Select(arr => arr.Distinct()) 
           .SelectMany(s => s) 
           .GroupBy(s => s) 
           .Select(grp => new { Text = grp.Key, Count = grp.Count() }) 
           .OrderByDescending(t => t.Count) 
           .ToList(); 

给出你{A,4},{B,4},{D,4},{C,3}

0
var result = new IEnumerable<String>[] {arr1, arr2, arr3, arr4, arr5, arr6} 
       .SelectMany(a => a) 
       .GroupBy(s => s) 
       .GroupBy(g => g.Count()) 
       .OrderByDescending(g => g.Key) 
       .FirstOrDefault() 
       .SelectMany(g => g.Key); 
0

你的问题不清楚,你还没有明确的规定,你在找什么。一般来说,您可以将所有数组组合到一个大数组中并计算不同的元素。然后通过订购元素,您可以对“最常见”做任何打算。

static void Main() 
{ 
    var arr1 = new[] { "A", "B", "C", "D" }; 
    var arr2 = new[] { "A", "D" }; 
    var arr3 = new[] { "A", "B", }; 
    var arr4 = new[] { "C", "D" }; 
    var arr5 = new[] { "B", "C", "D" }; 
    var arr6 = new[] { "B", "A", }; 
    List<string> combined = Combine(arr1, arr2, arr3, arr4, arr5, arr6); 

    var ordered = combined.OrderBy(i => i);//sorted list will probably help other functions work more quickly such as distinct 
    var distinct = ordered.Distinct(); 

    var counts = new Dictionary<string, int>(); 

    foreach (var element in distinct) 
    { 
     var count = ordered.Count(i => i == element); 
     counts.Add(element, count); 
    } 

    var orderedCount = counts.OrderByDescending(c => c.Value); 

    foreach (var count in orderedCount) 
    { 
     Console.WriteLine("{0} : {1}", count.Key, count.Value); 
    } 
    Console.ReadLine(); 
} 

private static List<string> Combine(string[] arr1, string[] arr2, string[] arr3, string[] arr4, string[] arr5, string[] arr6) 
{ 
    List<string> combined = new List<string>(); 
    combined.AddRange(arr1); 
    combined.AddRange(arr2); 
    combined.AddRange(arr3); 
    combined.AddRange(arr4); 
    combined.AddRange(arr5); 
    combined.AddRange(arr6); 
    return combined; 
} 

输出:A:4,B:4,d:4,C:3