在列表中查找一系列相同的数字

时间:2014-07-10 22:13:25

标签: c# .net

我有一个包含1或0的项目列表,我希望仅在列表中背靠背有6个1的情况下输出项目。因此,如果此列表中的项目是六个一组的一部分,则只写入控制台。

1 1 1 1 1 1 0 1 1 1  0

在上面的列表中,前六个项目将被输出,但是底部的三个1s项目不会,因为它们不属于六个一组。

这是LINQ还是RegEx的工作?

4 个答案:

答案 0 :(得分:1)

您可以将所有值连接到字符串中,然后将其拆分为零。从子字符串中选择至少包含6个字符的字符串:

List<int> values = new List<int> { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 };

var series = String.Concat(values)
                   .Split(new[] { '0' }, StringSplitOptions.RemoveEmptyEntries)
                   .Where(s => s.Length >= 6);

对于给定的输入数据系列将包含单个项目"111111",您可以将其输出到控制台。

答案 1 :(得分:1)

经典游程长度编码,O(n),惰性求值,堆栈不可知,任何等价类型的泛型。

public void TestRunLength()
{
    var runs = new List<int>{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 0, 4};

    var finalGroup = RunLength(runs).FirstOrDefault(i => i.Count == 6 && i.First() == 1);
}

private IEnumerable<List<T>> RunLength<T>(IEnumerable<T> source) where T : IEquatable<T>
{
    T current = default(T);

    var requiresInit = true;

    var list = new List<T>();

    foreach (var i in source)
    {
        if (requiresInit)
        {
            current = i;

            requiresInit = false;
        }

        if (i.Equals(current))
        {
            list.Add(i);
        }
        else
        {
            yield return list;

            list = new List<T>{ i };

            current = i;
        }
    }

    if (list.Any())
    {
        yield return list;
    }
}

因为它是懒惰的,它适用于无限序列(是的,我知道它不是无限的,但它很大)!

public void TestRunLength()
{
    var random = new Random();

    var runs = Enumerable.Range(int.MinValue, int.MaxValue)
                         .Select(i => random.Next(0, 10));

    var finalGroup = RunLength(runs)
        .FirstOrDefault(i => i.Count == 6);
}

答案 2 :(得分:0)

如果将数字连接成字符串,也可以使用Regex。但我更喜欢linq:

var bits = new List<int> {1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};

int bitCountPerGroup = 6;
var result = bits                    // (1)        (2)
            .Select((x,idx) => bits.Skip(idx).TakeWhile(y => y == x))
            .Where(g => g.Count() == bitCountPerGroup); // (3)

foreach (var set in result)
     Console.WriteLine(string.Join(" ", set));

此代码从数字(1)开始为每个数字设置一个数字集,只要它们相等(2),就可以获取下一个数字。然后过滤组,只获得那些有6个数字的组(3)。

答案 3 :(得分:0)

例如,如果您的列表大小未知或更好,您不知道其中的项目您可以执行此递归示例(请注意,我放置了更多的零,因此它将获取2组数据,它可以使用你也),并传递给amout的方法分组:

//this is the datastructure to hold the results
static List<KeyValuePair<string, List<int>>> Set = new List<KeyValuePair<string, List<int>>>();

private static void GetData(List<int> lst, int group)
{
    int count = 1;

    int pivot = lst.First();

    if (lst.Count < group)
    {
        return;
    }
    else
    {
        foreach (int i in lst.Skip(1))
        {
            if (i == pivot)
            {
                count++;
            }
            else if (count == group)
            {
                Set.Add(new KeyValuePair<string, List<int>>("Set of items " + pivot, lst.Take(count).ToList()));
                GetData(lst.Skip(count).ToList(), group);
                break;
            }
            else
            {
                GetData(lst.Skip(count).ToList(), group);
                break;
            }
        }
    }
}

然后在Main():

static void Main(string[] args)
{
     List<int> test = new List<int> { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 };
     GetData(test, 6);
     foreach (var item in Set)
     {
         Console.WriteLine("\t" + item.Key);
         foreach (var subitem in item.Value)
         {
             Console.WriteLine(subitem);
         }
     }
}