使用LINQ将列表列入另一个列表的次数

时间:2013-09-08 15:48:19

标签: c# .net linq

我有一个整数列表

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

我想知道它在另一个List中的次数。例如

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 个答案:

答案 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();
}

答案 1 :(得分: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;
    }

这是你需要的吗? 感谢。