@Nullable public static Range create(final int begin, final int end) { if (begin < 0 || begin >= end) { return null; } return new Range(begin, end); }
@Nullable public static Range create(final int singletonValue) { return singletonValue < 0 ? null : new Range(singletonValue, singletonValue + 1); }
@Nullable public static Range enclose(final Iterable<Range> ranges) { int begin = Integer.MAX_VALUE; int end = Integer.MIN_VALUE; for (final Range range : ranges) { begin = Math.min(range.begin, begin); end = Math.max(range.end, end); } return begin >= end ? null : new Range(begin, end); }
@Nullable public static Range intersection(final Iterable<Range> ranges) { int begin = Integer.MIN_VALUE; int end = Integer.MAX_VALUE; for (final Range range : ranges) { begin = Math.max(begin, range.begin); end = Math.min(end, range.end); if (begin >= end) { return null; } } return begin > Integer.MIN_VALUE ? new Range(begin, end) : null; }
@Nullable public static Range enclose(final int... values) { int begin = Integer.MAX_VALUE; int end = Integer.MIN_VALUE; for (final int value : values) { if (value < 0) { return null; } begin = Math.min(begin, value); end = Math.max(end, value + 1); } return begin >= end ? null : new Range(begin, end); }
public static List<Range> merge(final Iterable<Range> ranges) { final List<Range> sortedRanges = Ordering.natural().sortedCopy(ranges); int i = 0; while (i < sortedRanges.size() - 1) { final Range range1 = sortedRanges.get(i); final Range range2 = sortedRanges.get(i + 1); if (range1.end >= range2.begin) { final Range merged = new Range(Math.min(range1.begin, range2.begin), Math.max( range1.end, range2.end)); sortedRanges.set(i, merged); sortedRanges.remove(i + 1); } else { ++i; } } return sortedRanges; }
public List<Range> split(final Iterable<Range> ranges) { final List<Range> sortedRanges = separate(ranges); final List<Range> result = Lists.newArrayList(); int index = this.begin; for (final Range range : sortedRanges) { if (range.begin >= this.end) { break; } if (range.begin > index) { result.add(new Range(index, range.begin)); index = range.begin; } if (range.end > index) { final int end = Math.min(range.end, this.end); result.add(index == range.begin && end == range.end ? range : new Range(index, end)); index = end; } } if (index < this.end) { result.add(new Range(index, this.end)); } return result; }
public static List<Range> separate(final Iterable<Range> ranges) { final List<Range> sortedRanges = Lists.newArrayList(ranges); boolean overlaps = true; while (overlaps) { overlaps = false; Collections.sort(sortedRanges); for (int i = 0; i < sortedRanges.size() - 1; ++i) { final Range range1 = sortedRanges.get(i); final Range range2 = sortedRanges.get(i + 1); if (range1.end > range2.begin) { sortedRanges.remove(i); if (range1.begin < range2.begin) { sortedRanges.add(new Range(range1.begin, range2.begin)); } if (range1.end < range2.end) { sortedRanges.remove(i); // former i + 1 sortedRanges.add(new Range(range2.begin, range1.end)); sortedRanges.add(new Range(range1.end, range2.end)); } else if (range1.end > range2.end) { sortedRanges.add(new Range(range2.end, range1.end)); } overlaps = true; break; } } } return sortedRanges; }