/** 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 virtual Interval DifferenceNotProperlyContained(Interval other) { Interval diff = null; // other.a to left of this.a (or same) if (other.StartsBeforeNonDisjoint(this)) { diff = Interval.Create(Math.Max(this.a, other.b + 1), this.b); } // other.a to right of this.a else if (other.StartsAfterNonDisjoint(this)) { diff = Interval.Create(this.a, other.a - 1); } return(diff); }
/** 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 virtual Interval DifferenceNotProperlyContained( Interval other ) { Interval diff = null; // other.a to left of this.a (or same) if ( other.StartsBeforeNonDisjoint( this ) ) { diff = Interval.Create( Math.Max( this.a, other.b + 1 ), this.b ); } // other.a to right of this.a else if ( other.StartsAfterNonDisjoint( this ) ) { diff = Interval.Create( this.a, other.a - 1 ); } return diff; }
/** Return a new set with the intersection of this set with other. Because * the intervals are sorted, we can use an iterator for each list and * just walk them together. This is roughly O(min(n,m)) for interval * list lengths n and m. */ public IIntSet And(IIntSet other) { if (other == null) { //|| !(other instanceof IntervalSet) ) { return(null); // nothing in common with null set } var myIntervals = this.intervals; var theirIntervals = ((IntervalSet)other).intervals; IntervalSet intersection = new IntervalSet(); int mySize = myIntervals.Count; int theirSize = theirIntervals.Count; int i = 0; int j = 0; // iterate down both interval lists looking for nondisjoint intervals while (i < mySize && j < theirSize) { Interval mine = myIntervals[i]; Interval theirs = theirIntervals[j]; //[email protected]("mine="+mine+" and theirs="+theirs); if (mine.StartsBeforeDisjoint(theirs)) { // move this iterator looking for interval that might overlap i++; } else if (theirs.StartsBeforeDisjoint(mine)) { // move other iterator looking for interval that might overlap j++; } else if (mine.ProperlyContains(theirs)) { // overlap, add intersection, get next theirs intersection.Intervals.Add(theirs); j++; } else if (theirs.ProperlyContains(mine)) { // overlap, add intersection, get next mine intersection.Intervals.Add(mine); i++; } else if (!mine.Disjoint(theirs)) { // overlap, add intersection intersection.Add(mine.Intersection(theirs)); // Move the iterator of lower range [a..b], but not // the upper range as it may contain elements that will collide // with the next iterator. So, if mine=[0..115] and // theirs=[115..200], then intersection is 115 and move mine // but not theirs as theirs may collide with the next range // in thisIter. // move both iterators to next ranges if (mine.StartsAfterNonDisjoint(theirs)) { j++; } else if (theirs.StartsAfterNonDisjoint(mine)) { i++; } } } return(intersection); }