如何查找数组中所有超过阈值的连续元素的索引

时间:2019-01-15 02:20:57

标签: c#

我正在尝试使用c#为一维整数数组中出现次数超过阈值的所有连续元素查找索引

double[] x = new double[20]{1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,0,0,0,1,1};

我想获得此x []向量的索引,如下所示,用于0个值

threshold=4

start-index[0] =2
  end-index[0] =5

start-index[1] =8
  end-index[1] =11

我尝试使用此代码,但是其中有很多问题

public void myFunc(double[] x, ref List<int> start, ref List<int> end,int matchingVal,int threshold)
    {
        int count = 0;
        for (int i = 0; i < x.Length; i++)
        {
            for (int j = i+1; j < threshold; j++)
            {
                if (x[i] == x[j] && x[i] == matchingVal)
                {
                    count++;
                }
                else
                {
                    break;//no contiguous element
                }
                if (count >= threshold)
                {
                    start.Add(i);
                    end.Add(i + count);
                    count = 0;
                }
                else
                    continue;
            }
        }
    }

2 个答案:

答案 0 :(得分:3)

如果您愿意使用MoreLINQ,请考虑使用GroupAdjacent

下面是一个示例。基本上,它使用原始数组,使用Select来包含索引,使用GroupAdjacent将相邻的值组合在一起,使用WhereCount来检查至少有4个相邻的值,然后使用Select来投影匿名类型,包括该值及其第一个和最后一个索引(可以将其更改为投影成所需的任何具体类型)。 然后使用string.Join将其写入控制台,以便您查看结果。

using System;
using System.Linq;
using MoreLinq;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            double[] x = new double[20] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 };

            var results = x.Select((value, index) => new { value, index })
                .GroupAdjacent(z => z.value)
                .Where(z => z.Count() >= 4)
                .Where(z => z.Key == 0) // it is unclear whether you want to filter for specific values - if so, this is how to do it
                .Select(z =>
                    new { value = z.Key, firstIndex = z.First().index, lastIndex = z.Last().index })
                .ToList();

            Console.WriteLine(string.Join(Environment.NewLine, results.Select(z => $"{z.value} - {z.firstIndex} - {z.lastIndex}")));
            Console.ReadLine();
        }
    }
}

答案 1 :(得分:1)

已更新添加了更多测试,并通过@AntonínLejsek

解决了一个问题

给予

public static IEnumerable<(int start, int finish)> GetStuff(int thresh, double[] ary)
{
   int start = 0, count = 1;

   for (var i = 0; i < ary.Length - 1; i++, count++)
      if (ary[i] == ary[i + 1])
      {
         if (count == 1) start = i;
      }
      else
      {
         if (count >= thresh) yield return (start, i);
         count = 0; 
      }

   if (count >= thresh) yield return (start, ary.Length-1);
}

用法

foreach (var tuple in GetStuff(3,ary))
   Console.WriteLine($"start : {tuple.start}, finish : {tuple.finish}");

输出

var ary = new double[] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1 }; 

start : 2, finish : 5
start : 8, finish : 11
start : 12, finish : 14
start : 15, finish : 17

var ary = new double[] { 1, 1, 1 ,0 };

start : 0, finish : 2

var ary = new double[] { 1, 1, 1 };

start : 0, finish : 2