在列表中找到一系列相同的数字
本文关键字:数字 一系列 列表 | 更新日期: 2023-09-27 18:12:20
我有一个包含1或0的项目列表,我希望仅在列表中有六个背靠背1的地方输出项目。因此,只有当列表中的项目是一组六个项目中的一部分时,才会写入控制台。
11111101110
在上面的列表中,前6个项目将被输出,但底部的3个15不会输出,因为它们不是6个项目的一部分。
这是LINQ或RegEx的工作吗?
您可以将所有值连接成字符串,然后将其除以零。从子字符串中选择至少有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"
,您可以将其输出到控制台。
经典运行长度编码,0 (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);
}
如果您将数字连接到字符串中,可能也可以使用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)的组。
如果例如你的列表是一个未知的大小,或者更好的,你不知道其中的项目,你可以做这个递归的例子(注意,我放置了更多的零,所以它会获取2组数据,它也与你的工作),并传递给方法的数量分组:
//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;
}
}
}
}
Then in 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);
}
}
}