Re[3]: [Request for help] CompositeRange<T>
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 30.09.16 20:57
Оценка: 23 (1)
Здравствуйте, Sinix, Вы писали:

AVK>>А можно сразу вопрос — чем это лучше просто Range<T>[]?

S>Только готовыми операциями над наборами диапазонов, больше ничем.

Известное правило Мейера говорит, что все методы, которые можно сделать свободными функциями, нужно сделать свободными функциями.

S>Для CompositeRange можно срезать кучу углов, т.к. поддиапазоны отсортированы


Ну то есть фишка в том, что внутри диапазоны всегда отсортированы? Тогда понятно.

Из того что мне требовалось:
1) Мне нужен механизм ассоциаций с диапазонами некоей допинформации. Т.е. Range<T, TValue>
2) Алгоритм, который гарантирует отсутствие наложения диапазонов, но при этом все границы должны сохраняться, т.е. это не просто мердж. К этому еще необходимо склеивать допинформацию (Т.е. на входе Range<T, TValue>[], на выходе Range<T, TValue[]>[]). Вот как оно выглядит у меня (я, вроде, уже постил):
internal static IEnumerable<RangeDescriptor> NormalizeRanges(IEnumerable<Transition> source)
{
    var ranges =
        source
            .SelectMany(t => t.Ranges.Select(r => new {r.Start, r.End, t.Target}))
            .ToArray();
    var points =
        ranges
            .SelectMany(
                r =>
                    new[]
                    {
                        new {Pos = (int)r.Start, Targets = new List<State>()},
                        new {Pos = r.End + 1, Targets = new List<State>()}
                    })
            .OrderBy(p => p.Pos)
            .ToArray();
    foreach (var range in ranges)
        foreach (var point in
                points
                    .SkipWhile(p => p.Pos < range.Start)
                    .TakeWhile(p => p.Pos <= range.End))
            point.Targets.Add(range.Target);
    return
        points
            .Zip(points.Skip(1), (p1, p2) => new {Start = p1, End = p2})
            .Where(r => r.Start.Targets.Any() && r.Start.Pos < r.End.Pos)
            .Select(
                r =>
                    new RangeDescriptor(
                        new CharRange(
                            (ushort) r.Start.Pos,
                            (ushort) (r.End.Pos - 1)),
                        r.Start.Targets.ToArray()));
}

Обсуждение алгоритма
Автор: AndrewVK
Дата: 20.02.14

Как это правильно генерализовать я
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.