public static IntervalList IntersectSorted(IntervalList sequence1, IntervalList sequence2, IComparer <int> comparer) { var result = new IntervalList(); var steps = 0; //var ds = DateTime.Now; var s1 = sequence1.Intervals.Count; var s2 = sequence2.Intervals.Count; var smaller = s1 < s2 ? sequence1 : sequence2; var bigger = smaller == sequence1 ? sequence2 : sequence1; var sc = smaller.Intervals.Count; var bc = bigger.Intervals.Count; var bix = 0; var six = 0; Interval s = null; Interval b = null; var bchanged = true; var schanged = true; while (six < sc && bix < bc) { steps++; if (schanged) { s = smaller.Intervals[six]; schanged = false; } if (bchanged) { if (bc > 10000 && sc < 100) { bix = bigger.SearchByStartIndexBefore(s, bix); } b = bigger.Intervals[bix]; bchanged = false; } var r = s.Compare(b); if (r == 0) { //result.Intervals.Add(s.Intersect(b)); result.AddIntervalToEnd(s.Intersect(b)); if (s.End > b.End) { bix++; bchanged = true; } else { six++; schanged = true; } } if (r < 0) { six++; schanged = true; } if (r > 0) { bix++; bchanged = true; } } //var de = DateTime.Now; //Utilities.Logger.WriteToFile(string.Format("IntersectSorted({0},{1}):{4} in {2} steps, {3} ms ", sequence1, sequence2, steps, de.Subtract(ds).TotalMilliseconds, result.Count)); return(result); }
public static IntervalList SortedExcept(IntervalList sequence1, IntervalList sequence2, IComparer <int> comparer) { var result = new IntervalList(); var steps = 0; //var ds = DateTime.Now; var smaller = sequence1; var bigger = sequence2; var bix = 0; var six = 0; var sc = smaller.Intervals.Count; var bc = bigger.Intervals.Count; if (sc == 0) { return(result); } var s1 = smaller.FirstInterval == null ? 0 : smaller.FirstInterval.Start; var b1 = bigger.FirstInterval == null ? 0 : bigger.FirstInterval.Start; var se = smaller.LastInterval == null ? 0 : smaller.LastInterval.End; var be = bigger.LastInterval == null ? 0 : bigger.LastInterval.End; if (bc == 0 || se < b1 || be < s1) { return(smaller.Copy()); } var limit = 10; if (sc > limit) { var tsix = smaller.Intervals.BinarySearch(bigger.FirstInterval, IntervalList.startcomparer); if (tsix > sc) { six = sc - 1; } if (tsix < 0) { six = ~tsix; six = six > 0 ? six - 1 : six; } for (int i = 0; i < six; i++) { result.AddInterval(smaller.Intervals[i].Copy()); } } if (bc > limit) { var tbix = bigger.Intervals.BinarySearch(smaller.FirstInterval, IntervalList.startcomparer); if (tbix > bc) { bix = bc - 1; } if (tbix < 0) { bix = ~tbix; bix = bix > 0 ? bix - 1 : bix; } } Interval s = smaller.Intervals.FirstOrDefault(); Interval b = bigger.Intervals.FirstOrDefault(); Interval snext = six < sc ? smaller.Intervals[six] : s; Interval bnext = bix < bc ? bigger.Intervals[bix] : b; var evalb = true; while (snext != null) { steps++; s = snext; b = bnext; var r = b == null?-1: s.Compare(b); if (r == 0) { var except = s.Except(b); var hasany = except != null && except.Count > 0; if (!hasany) { six++; snext = six < sc ? smaller.Intervals[six] : null; continue; } else { if (except.Count == 2) { //result.Intervals.Add(except[0]); result.AddIntervalToEnd(except[0]); snext = except[1]; continue; } else { snext = except[0]; } s = snext; } if (s.End > b.End) { bix++; evalb = true; } else { // result.Intervals.Add(s); result.AddIntervalToEnd(s.Copy()); six++; snext = six < sc ? smaller.Intervals[six] : null; } } if (r < 0) { //result.Intervals.Add(s); result.AddIntervalToEnd(s.Copy()); six++; snext = six < sc ? smaller.Intervals[six] : null; } if (r > 0) { // if (bigger.Intervals.Count > 1000000) { } bix++; if (bc > 10000 && sc < 100) { bix = bigger.SearchByStartIndexBefore(s, bix); } evalb = true; } if (evalb) { evalb = false; bnext = bix < bc ? bigger.Intervals[bix] : null; } } //var de = DateTime.Now; //Utilities.Logger.WriteToFile(string.Format("SortedExcept({0},{1}):{4} in {2} steps, {3} ms ", sequence1, sequence2, steps, de.Subtract(ds).TotalMilliseconds, result.Count)); return(result); }