C#中连续相等元素的序列

本文关键字:元素 连续 | 更新日期: 2023-09-27 18:30:03

您会得到一个带有数字的数组。找到连续相等的元素,并打印连续相等元素的最大序列。如何找到并打印最大的一个。

    int[] array = new int[] {1,1,2,3,555,4,34,4,4,4,6,6,888,8,8,8,8,7,7,77};
    int start = 0;
    ....
    for (int i = 0; i < array.Length; i++)
    {
        if (start == array[i])
        {
            Console.Write(start + " " + array[i] + " ");                
        } 
        start = array[i]; 
    } 

C#中连续相等元素的序列

您可以使用此扩展和Lookup<TKey, TElement>:

public static IEnumerable<T> GetConsecutiveEqual<T>(this IEnumerable<T> seq)
{
    if(!seq.Any())
        yield break;
    var comparer = EqualityComparer<T>.Default;
    T last = seq.First();
    using (IEnumerator<T> e = seq.GetEnumerator())
    {
        while (e.MoveNext())
        {
            if (comparer.Equals(last, e.Current))
            {
                yield return last;
                yield return e.Current;
                if(!e.MoveNext()) break;
            }
            last = e.Current;
        }
    }
}

你可以这样使用:

int[] array = new int[] { 1, 1, 2, 3, 555, 4, 34, 4, 4, 4, 6, 6, 888, 8, 8, 8, 8, 7, 7, 77,77 };
var conseqEquals = array.GetConsecutiveEqual(); ;    
var lookup = conseqEquals.ToLookup(i => i);
var maxGroup = lookup.OrderByDescending(g => g.Count()).First();
string allNums = string.Join(",", maxGroup); // 8,8,8,8

如果你想看到所有的最大计数,你可以使用这种方法:

// note that the array now contains 4 consecutive 4, 4, 4, 4:
int[] array = new int[] { 1, 1, 2, 3, 555, 4, 34, 4, 4, 4, 4, 6, 6, 888, 8, 8, 8, 8, 7, 7, 77,77 };
var conseqEquals = array.GetConsecutiveEqual(); ;    
int maxGroupCount = lookup.Max(g => g.Count());
var allWithMaxCount = lookup.Where(g => g.Count() == maxGroupCount)
    .Select(mg => string.Join(",", mg));
string allNums = string.Join(" | ", allWithMaxCount); // 4,4,4,4 | 8,8,8,8

更新:您也可以使用受Enumerable.GroupBy启发的扩展,并返回相邻/连续项目组:

public static IEnumerable<IGrouping<TKey, TSource>> GroupAdjacent<TSource, TKey>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector)
    {
        TKey last = default(TKey);
        bool haveLast = false;
        List<TSource> list = new List<TSource>();
        foreach (TSource s in source)
        {
            TKey k = keySelector(s);
            if (haveLast)
            {
                if (!k.Equals(last))
                {
                    yield return new GroupOfAdjacent<TSource, TKey>(list, last);
                    list = new List<TSource>();
                    list.Add(s);
                    last = k;
                }
                else
                {
                    list.Add(s);
                    last = k;
                }
            }
            else
            {
                list.Add(s);
                last = k;
                haveLast = true;
            }
        }
        if (haveLast)
            yield return new GroupOfAdjacent<TSource, TKey>(list, last);
    }
}

和使用的类(都放在扩展库中):

public class GroupOfAdjacent<TSource, TKey> : IEnumerable<TSource>, IGrouping<TKey, TSource>
{
    public TKey Key { get; set; }
    private List<TSource> GroupList { get; set; }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return ((System.Collections.Generic.IEnumerable<TSource>)this).GetEnumerator();
    }
    System.Collections.Generic.IEnumerator<TSource> System.Collections.Generic.IEnumerable<TSource>.GetEnumerator()
    {
        foreach (var s in GroupList)
            yield return s;
    }
    public GroupOfAdjacent(List<TSource> source, TKey key)
    {
        GroupList = source;
        Key = key;
    }
}

您可以类似地使用它,但扩展方法在许多情况下都很方便:

var groupConsecutive = array.GroupAdjacent(i => i);
int maxGroupCount = groupConsecutive.Max(g => g.Count());
var allWithMaxCount = groupConsecutive.Where(g => g.Count() == maxGroupCount)
    .Select(mg => string.Join(",", mg));
string allNums = string.Join(" | ", allWithMaxCount);