Здравствуйте, 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
Как это правильно генерализовать я
![](/Forum/Images/xz.gif)
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>