如何计算linq中的序列长度

时间:2017-09-18 14:18:17

标签: arrays list linq

我有一个1和0的列表。说:1,1,1,0,0,1,1,1,1,1,0,1,1,1,0,0,0,1

我希望获得1s序列的最大长度。

在这种情况下,序列是3,5,3,1,最大值是5.

我有这个代码(使用来自S.O.问题的回答:Getting pair set using linq

var list = new[]{1,1,1,0,0,1,1,1,1,1,0,1,1,1,0,0,0,1}.ToList();
var pairs = list.Where( (e,i) => i < list.Count - 1 )
            .Select( (e,i) => new { A = e, B = list[i+1] }  ).ToList();
var analyzed = pairs.ConvertAll( p=> new ... not sure how to continue  

6 个答案:

答案 0 :(得分:2)

我也不推荐使用linq,因为当你可以轻松获得解决方案时需要更多的时间来解决问题。

我使用索引0来定位1的长度。

var list = new[]{1,1,1,0,0,1,1,1,1,1,0,1,1,1,0,0,0,1}.ToList();

int previousIndex= -1;
int index = list.IndexOf(0);

int max = index < 0 ? list.Count() : 0;
while(index >=0)
{
    int currentLength = index - previousIndex - 1;
    max = max > currentLength ? max : currentLength;
    previousIndex = index;
    index = list.IndexOf(0, index + 1);

    // if sequence of 1 in the end of array
    if(index < 0)
    {
        currentLength = list.Count() -  previousIndex - 1;
        max = max > currentLength ? max : currentLength;
    }
}

Console.WriteLine(max);

答案 1 :(得分:2)

一个非常好且可重复使用的解决方案,使用thisGroupAdjacentBy扩展名dtb回答:

public static IEnumerable<IEnumerable<T>> GroupAdjacentBy<T>(this IEnumerable<T> source, Func<T, T, bool> predicate)
{
    using (var e = source.GetEnumerator())
    {
        if (e.MoveNext())
        {
            var list = new List<T> { e.Current };
            var pred = e.Current;
            while (e.MoveNext())
            {
                if (predicate(pred, e.Current))
                {
                    list.Add(e.Current);
                }
                else
                {
                    yield return list;
                    list = new List<T> { e.Current };
                }
                pred = e.Current;
            }
            yield return list;
        }
    }
}

var list = new[] { 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1 }.ToList();
var grouped = list.GroupAdjacentBy((x, y) => x == y); // Group identical adjacent elements together into sublists
int result = grouped.Max(s => s.Count()); // Get longest sublist

答案 2 :(得分:1)

使用扩展方法为Split提供与IEnumerable类似的String.Split

public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> src, Func<T, bool> atSplit) {
    IEnumerable<T> NextSplit(IEnumerator<T> e) {
        while (!atSplit(e.Current)) {
            yield return e.Current;
            if (!e.MoveNext())
                yield break;
        }
    }

    var srce = src.GetEnumerator();
    while (srce.MoveNext())
        yield return NextSplit(srce);
}

然后你的回答是:

var ans = list.Split(n => n == 0).Select(sl => sl.Count()).Max();

答案 3 :(得分:1)

这似乎非常容易:

var list = new[]{1,1,1,0,0,1,1,1,1,1,0,1,1,1,0,0,0,1}.ToList();

var maxOnes =
    list
        .Aggregate(
            new { Max = 0 , Current = 0 },
            (a, x) => x == 0
                ? new { Max = a.Max , Current = 0 }
                : new { Max = a.Max > a.Current + 1
                    ? a.Max
                    : a.Current + 1 , Current = a.Current + 1 })
        .Max;

这是一次通过列表非常高效。

答案 4 :(得分:1)

不确定为什么其他答案过于复杂的LINQ,迭代器和谓词......当基本foreach循环足以找到最大连续序列计数时。没什么好看的:

public static int GetMaxSequenceCount( IEnumerable<int> items, int match )
{
    int max = 0;
    int total = 0;

    foreach( int i in items )
    {
        if( i == match )
        {
            total++;
            max = total > max ? total : max;
            continue;
        }

        total = 0;
    }

    return max;
}

答案 5 :(得分:1)

几个较短的选择:

if tableView == innerTableView