Tôi tin rằng tối ưu nhất cách để làm điều này là tạo ra một phương thức "LINQ giống như" mở rộng bằng cách sử dụng một khối lặp. Điều này cho phép bạn thực hiện phép tính thực hiện một lần truyền dữ liệu của bạn. Lưu ý rằng hiệu suất không quan trọng chút nào nếu bạn chỉ muốn thực hiện phép tính trên một mảng nhỏ các số. Tất nhiên đây thực sự là vòng lặp của bạn trong ngụy trang.
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);
}
}
}
Lưu ý rằng phương pháp mở rộng là chung chung và bạn có thể sử dụng nó ở bất kỳ loại nào. Giá trị được so sánh cho sự bình đẳng sử dụng Object.Equals
. Tuy nhiên, nếu bạn muốn bạn có thể vượt qua một số IEqualityComparer<T>
để cho phép tùy chỉnh cách so sánh giá trị.
Bạn có thể sử dụng phương pháp như thế này:
var numbers = new[] { 4, 1, 1, 3, 3, 2, 5, 3, 2, 2 };
var runLengths = numbers.ToRunLengths();
Đối với bạn dữ liệu đầu vào kết quả sẽ là những tuples:
4 1
1 2
3 2
2 1
5 1
3 1
2 2
Nguồn
2012-07-04 13:45:22
Thật khó để xem như thế nào chiều dài mảng có thể được cố định ở mức 6 nếu một ví dụ là 4, 1, 1, 3, 3, 2, 5, 3, 2, 2 ... –
Bây giờ hãy kiểm tra câu hỏi, vui lòng – sandeep
Tại sao đầu ra có các khóa trùng lặp cho các số "2" và "3"? Bạn không nên mong đợi một đầu ra là "4 => 1, 1 => 2, 3 => 3, 2 => 3, 5 => 1"? –