Реализация c # получить диапазон значений и объединение этих диапазонов - PullRequest
3 голосов
/ 11 мая 2011

У меня есть ситуация, которая хорошо объясняется в этом вопросе:

Пересечение диапазона / соединение

Мне нужна реализация C # (может быть, коллекция), которая берет список диапазонов (целых) и объединяет их. Затем мне нужно перебрать все целые числа в этой коллекции (также числа между диапазонами) Есть ли какая-нибудь библиотека / реализация, чтобы мне не приходилось переписывать все самому?

Ответы [ 5 ]

3 голосов
/ 11 мая 2011

Вы можете взглянуть на эту реализацию и посмотреть, будет ли она соответствовать вашим потребностям.

Объединить диапазоны с Range.Coalesce:

var range1 = Range.Create(0, 5, "Range 1");
var range2 = Range.Create(11, 41, "Range 2");
var range3 = Range.Create(34, 50, "Range 3");
var ranges = new List<Range> { range1, range2, range3 };
var unioned = Range.Coalesce(ranges);

Итерировать подиапазоны с .Iterate:

foreach (var range in unioned)
{
    foreach (int i in range.Iterate(x => x + 1))
    {
        Debug.WriteLine(i);
    }
}
1 голос
/ 11 мая 2011

Ниже приведена ванильная реализация Linq:

var r1 = Enumerable.Range(1,10);
var r2 = Enumerable.Range(20,5);
var r3 = Enumerable.Range(-5,10);

var union = r1.Union(r2).Union(r3).Distinct();

foreach(var n in union.OrderBy(n=>n))
    Console.WriteLine(n);
1 голос
/ 11 мая 2011

Самое простое, что приходит мне в голову - это использовать Enumerable.Range, а затем обрабатывать различные IEnumerable с помощью стандартных операторов linq.Что-то вроде:

var list = Enumerable.Range(1, 5)
.Concat(Enumerable.Range(7, 11))
.Concat(Enumerable.Range(13, 22))

foreach(var number in list)
  // Do something

Очевидно, что вы также можете использовать Union и Intersect ... очевидно, вы также можете поместить свои диапазоны в List<IEnumerable<int>> или что-то подобное, а затем перебрать элементы для создания единого спискаиз элементов:

var ranges = new List<IEnumerable<int>> 
{ 
    Enumerable.Range(1, 5), 
    Enumerable.Range(7, 11), 
    Enumerable.Range(10, 22) 
};
var unionOfRanges = Enumerable.Empty<int>();

foreach(var range in ranges)
    unionOfRanges = unionOfRanges.Union(range);

foreach(var item in unionOfRanges)
    // Do something
0 голосов
/ 11 мая 2011

Структура данных, которую вы ищете, называется «деревом интервалов».

В сети можно найти различные реализации.

Например, вот одна из них: http://www.emilstefanov.net/Projects/RangeSearchTree.aspx

0 голосов
/ 11 мая 2011

System.Collections.Generic.HashSet имеет только одну вещь:

  • UnionWith( IEnumerable<T> other ).Изменяет текущий объект HashSet, чтобы он содержал все элементы, которые присутствуют в нем, в указанной коллекции или в обоих.
  • IntersectWith( IEnumerable<T> other ).Изменяет текущий объект HashSet, чтобы он содержал только элементы, которые присутствуют в этом объекте и в указанной коллекции.
...