/** Return the interval with elements from this not in other; * other must not be totally enclosed (properly contained) * within this, which would result in two disjoint intervals * instead of the single one returned by this method. */ public Interval?DifferenceNotProperlyContained(Interval other) { Interval?diff = null; // other.a to left of this.a (or same) if (other.StartsBeforeNonDisjoint(this)) { diff = Interval.FromBounds(Math.Max(this.a, other.b + 1), this.b); } // other.a to right of this.a else if (other.StartsAfterNonDisjoint(this)) { diff = Interval.FromBounds(this.a, other.a - 1); } return(diff); }
/** Given the set of possible values (rather than, say UNICODE or MAXINT), * return a new set containing all elements in vocabulary, but not in * this. The computation is (vocabulary - this). * * 'this' is assumed to be either a subset or equal to vocabulary. */ public virtual IIntSet Complement(Interval vocabulary) { if (vocabulary.b < MinElement || vocabulary.a > MaxElement) { // nothing in common with this set return(null); } int n = intervals.Count; if (n == 0) { return(IntervalSet.Of(vocabulary)); } IntervalSet compl = new IntervalSet(); Interval first = intervals[0]; // add a range from 0 to first.a constrained to vocab if (first.a > vocabulary.a) { compl.Intervals.Add(Interval.FromBounds(vocabulary.a, first.a - 1)); } for (int i = 1; i < n; i++) { if (intervals[i - 1].b >= vocabulary.b) { break; } if (intervals[i].a <= vocabulary.a) { continue; } if (intervals[i - 1].b == intervals[i].a - 1) { continue; } compl.Intervals.Add(Interval.FromBounds(Math.Max(vocabulary.a, intervals[i - 1].b + 1), Math.Min(vocabulary.b, intervals[i].a - 1))); //// from 2nd interval .. nth //Interval previous = intervals[i - 1]; //Interval current = intervals[i]; //IntervalSet s = IntervalSet.Of( previous.b + 1, current.a - 1 ); //IntervalSet a = (IntervalSet)s.And( vocabularyIS ); //compl.AddAll( a ); } Interval last = intervals[n - 1]; // add a range from last.b to maxElement constrained to vocab if (last.b < vocabulary.b) { compl.Intervals.Add(Interval.FromBounds(last.b + 1, vocabulary.b)); //IntervalSet s = IntervalSet.Of( last.b + 1, maxElement ); //IntervalSet a = (IntervalSet)s.And( vocabularyIS ); //compl.AddAll( a ); } return(compl); }
public virtual IIntSet Complement(int minElement, int maxElement) { return(this.Complement(Interval.FromBounds(minElement, maxElement))); }
/** Add interval; i.e., add all integers from a to b to set. * If b<a, do nothing. * Keep list in sorted order (by left range value). * If overlap, combine ranges. For example, * If this is {1..5, 10..20}, adding 6..7 yields * {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}. */ public virtual void Add(int a, int b) { Add(Interval.FromBounds(a, b)); }
/** Create a set with all ints within range [a..b] (inclusive) */ public static IntervalSet Of(int a, int b) { return(Of(Interval.FromBounds(a, b))); }
/** Return the interval in common between this and o */ public Interval Intersection(Interval other) { return(Interval.FromBounds(Math.Max(a, other.a), Math.Min(b, other.b))); }