san*_*eep 5 .net c# linq algorithm
这是我的问题的一个场景:我有一个数组,说:
{ 4, 1, 1, 3, 3, 2, 5, 3, 2, 2 }
Run Code Online (Sandbox Code Playgroud)
结果应该是这样的(数组元素=>它的计数):
4 => 1
1 => 2
3 => 2
2 => 1
5 => 1
3 => 1
2 => 2
Run Code Online (Sandbox Code Playgroud)
我知道这可以通过实现for loop
.
但是谷歌使用LINQ使用较少的代码行没有成功,这使得这成为可能.
我相信最好的方法是使用迭代器块创建一个"LINQ-like"扩展方法.这使您可以对数据进行一次传递来执行计算.请注意,如果您只想对一小组数字执行计算,那么性能根本不重要.当然,这实际上是你的伪装循环.
static class Extensions {
public static IEnumerable<Tuple<T, Int32>> ToRunLengths<T>(this IEnumerable<T> source) {
using (var enumerator = source.GetEnumerator()) {
// Empty input leads to empty output.
if (!enumerator.MoveNext())
yield break;
// Retrieve first item of the sequence.
var currentValue = enumerator.Current;
var runLength = 1;
// Iterate the remaining items in the sequence.
while (enumerator.MoveNext()) {
var value = enumerator.Current;
if (!Equals(value, currentValue)) {
// A new run is starting. Return the previous run.
yield return Tuple.Create(currentValue, runLength);
currentValue = value;
runLength = 0;
}
runLength += 1;
}
// Return the last run.
yield return Tuple.Create(currentValue, runLength);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,扩展方法是通用的,您可以在任何类型上使用它.使用相等的值比较值Object.Equals
.但是,如果您愿意,可以传递一个IEqualityComparer<T>
允许自定义值的比较方式.
你可以使用这样的方法:
var numbers = new[] { 4, 1, 1, 3, 3, 2, 5, 3, 2, 2 };
var runLengths = numbers.ToRunLengths();
Run Code Online (Sandbox Code Playgroud)
对于输入数据,结果将是这些元组:
4 1 1 2 3 2 2 1 5 1 3 1 2 2
归档时间: |
|
查看次数: |
2223 次 |
最近记录: |