private IEnumerable <CharRange> ClipRange(CharRange range, IList <CharRange> excludedCharRanges) { char from = range.From; char to = range.To; foreach (var excludedRange in excludedCharRanges) { // If the range is fully excluded by the excluded range, yield nothing if (excludedRange.From <= from && excludedRange.To >= to) { yield break; } // Check if the excluded range is wholly contained within the range if (excludedRange.From > from && excludedRange.To < to) { // Split this range and return foreach (var charRange in ClipRange(new CharRange { From = @from, To = (char)(excludedRange.From - 1) }, excludedCharRanges)) { yield return(charRange); } // Second split foreach (var charRange in ClipRange(new CharRange { From = (char)(excludedRange.To + 1), To = to }, excludedCharRanges)) { yield return(charRange); } yield break; } // Trim the edges of the range if (to >= excludedRange.From && to <= excludedRange.To) { to = (char)(excludedRange.From - 1); } if (from >= excludedRange.From && from <= excludedRange.To) { from = (char)(excludedRange.To + 1); } } // If the range has been clipped away to nothing, then quit if (to < from) { yield break; } // Return the possibly clipped range yield return(new CharRange { From = from, To = to }); }
private IEnumerable <CharRange> FindNewRanges(CharRange range, List <CharRange> distinguishedRanges) { int a = 0; int b = distinguishedRanges.Count; int startIndex = 0; while (true) { int pivot = a + (b - a) / 2; int cmp = range.From - distinguishedRanges[pivot].From; if (cmp == 0) { startIndex = pivot; break; } if (cmp < 0) { b = pivot; } else { a = pivot; } } int a2 = startIndex; int b2 = distinguishedRanges.Count; char c = range.To == char.MaxValue ? range.To : (char)(range.To + 1); while (true) { int pivot = a2 + (b2 - a2) / 2; int cmp = c - distinguishedRanges[pivot].To; if (cmp == 0) { for (int i = startIndex; i <= pivot; ++i) { CharRange f = distinguishedRanges[i]; yield return(new CharRange { From = f.From, To = f.To == char.MaxValue ? f.To : (char)(f.To - 1) }); } yield break; } if (cmp < 0) { b2 = pivot; } else { a2 = pivot; } } }
public bool DistinguishRanges(CharSet other) { bool changes = false; ISet<CharRange> newRanges = new HashSet<CharRange>(); // For each of the ranges that this set contains, if there is another range that intersects // create new ranges so that there is no intersecting ranges for (int i = 0; i < ranges.Count; ++i ) { var r = ranges[i]; foreach (var r2 in other.ranges) { // If from is inside the range (not on borders), split the range if (r2.From > r.From && r2.From <= r.To) { var oldTo = r.To; r.To = (char) (r2.From - 1); var newRange = new CharRange { From = r2.From, To = oldTo }; newRanges.Add(newRange); changes = true; } // Same thing goes for to if (r2.To >= r.From && r2.To < r.To) { var oldTo = r.To; r.To = r2.To; var newRange = new CharRange { From = (char) (r2.To + 1), To = oldTo }; newRanges.Add(newRange); changes = true; } } newRanges.Add(r); } ranges = newRanges.ToList(); return changes; }
private IEnumerable<CharRange> ClipRange(CharRange range, IList<CharRange> excludedCharRanges) { char from = range.From; char to = range.To; foreach (var excludedRange in excludedCharRanges) { // If the range is fully excluded by the excluded range, yield nothing if (excludedRange.From <= from && excludedRange.To >= to) { yield break; } // Check if the excluded range is wholly contained within the range if (excludedRange.From > from && excludedRange.To < to ) { // Split this range and return foreach (var charRange in ClipRange(new CharRange {From = @from, To = (char)(excludedRange.From - 1)}, excludedCharRanges)) { yield return charRange; } // Second split foreach (var charRange in ClipRange(new CharRange { From = (char)(excludedRange.To + 1), To = to }, excludedCharRanges)) { yield return charRange; } yield break; } // Trim the edges of the range if (to >= excludedRange.From && to <= excludedRange.To) { to = (char)(excludedRange.From - 1); } if (from >= excludedRange.From && from <= excludedRange.To) { from = (char)(excludedRange.To + 1); } } // If the range has been clipped away to nothing, then quit if (to < from) yield break; // Return the possibly clipped range yield return new CharRange { From = from, To = to}; }