2013-11-14 123 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