2013-09-08 3 views
-4

Supose У меня есть список целых чиселСколько раз в СПИСКЕ в другом списке с помощью LINQ

List<int> l1 = new List<int> { 1, 4, 1}; 

Я хочу, чтобы узнать, сколько раз другой списка, что находится внутри этого one.For например

List<int> l2 = new List<int> { 1 , 1 } occours 1 time. 

List<int> l3 = new List<int> { 4, 1 } occours 1 time. 

List<int> l4 = new List<int> {1} occours 2 times. 

List<int> l5 = new List<int> {6,4,1} occours 0 time. 

List<int> l5 = new List<int> {4,1,1} occours 1 time. 

заранее спасибо

+2

Причина, по которой вы получаете downvoted, состоит в том, что вы не продемонстрировали, что пытались решить проблему самостоятельно. Отправьте свою лучшую попытку, и мы можем вам помочь. –

+0

У меня возникают проблемы с повторением значений с помощью Intersect. – user2757243

+0

Эта проблема на самом деле не проста. –

ответ

2

Моя идея заключается в создании словаря, который отображает каждый элемент в первоначальном списке, как часто это происходит. Затем я итеративно уменьшаю каждый элемент, соответствующий одному в под-списке, до тех пор, пока одно из значений не достигнет нуля, после чего я вернусь к числу полных итераций.

public static int CountSubsets<T>(this IList<T> list, IList<T> subList) 
{ 
    var grouped = list.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count()); 
    int count = 0; 
    while (RemoveSubset(grouped, subList)) 
     count++; 
    return count; 
} 

private static bool RemoveSubset<T>(Dictionary<T, int> dict, IList<T> subList) 
{ 
    foreach (T item in subList) 
    { 
     if (dict.ContainsKey(item) && dict[item] > 0) 
      dict[item]--; 
     else 
      return false; 
    } 

    return true; 
} 

Не обязательно самое эффективное или изящное решение, но оно должно работать.

Редактировать: Вот причудливый, но, вероятно, более медленный способ сделать это. Я очень доволен этим:

public static int CountSubsets2<T>(this IList<T> list, IList<T> subList) 
{ 
    var main = list.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count()); 
    var sub = subList.GroupBy(t => t).ToDictionary(t => t.Key, t => t.Count()); 
    return sub.Select(t => main.ContainsKey(t.Key) ? main[t.Key]/t.Value : 0).Min(); 
} 
+0

Обе реализации не работают для первого тестового примера. –

+0

@ UfukHacıoğulları Да. Он возвращает 1: http://dotnetpad.net/ViewPaste/FhimCk3liUW5YMfwx8U4Sw –

+0

Все тесты и понимание алгоритма здесь, я уверен, что первый работает нормально, а не проверял второй. –

0

Я думаю, что это самое простое решение и работа.

public int GetCount(List<int> source, List<int> innerList) 
    { 
     source = source.OrderBy(i => i).ToList(); 
     innerList = innerList.OrderBy(i => i).ToList(); 
     int count = 0; 
     for (var i = 0; i <= source.Count - innerList.Count; i++) 
     { 
      if (source.Skip(i).Take(innerList.Count).SequenceEqual(innerList)) 
      { 
       count++; 
      } 
     } 

     return count; 
    } 

Это тот, который вам нужен? Спасибо.