/* * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
package * by * This code is distributed in the hope * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
import java.util * version 2 for more details (a copy is included * accompanied * * You should have received a copy of the GNU General Public * 2 along with this work; if not, write to * Inc., 51 Franklin St, java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 2 import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Vector;
/** * Maintains a list of half-open intervals, called Spans. * A Span can be tested against the list of Spans * for intersection.
*/ publicclass Spans {
/** * This class will sort and collapse its span * entries after this many span additions via * the {@code add} method.
*/ privatestaticfinalint kMaxAddsSinceSort = 256;
/** * Holds a list of individual * Span instances.
*/ private List<Span> mSpans = new Vector<>(kMaxAddsSinceSort);
/** * The number of {@code Span} * instances that have been added * to this object without a sort * and collapse taking place.
*/ privateint mAddsSinceSort = 0;
public Spans() {
}
/** * Add a span covering the half open interval * including {@code start} up to * but not including {@code end}.
*/ publicvoid add(float start, float end) {
if (mSpans != null) {
mSpans.add(new Span(start, end));
if (++mAddsSinceSort >= kMaxAddsSinceSort) {
sortAndCollapse();
}
}
}
/** * Add a span which covers the entire range. * This call is logically equivalent to * {@code add(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY)} * The result of making this call is that * all future {@code add} calls are ignored * and the {@code intersects} method always * returns true.
*/ publicvoid addInfinite() {
mSpans = null;
}
/** * Returns true if the span defined by the half-open * interval from {@code start} up to, * but not including, {@code end} intersects * any of the spans defined by this instance.
*/ publicboolean intersects(float start, float end) { boolean doesIntersect;
if (mSpans != null) {
/* If we have added any spans since we last * sorted and collapsed our list of spans * then we need to resort and collapse.
*/ if (mAddsSinceSort > 0) {
sortAndCollapse();
}
/* The SpanIntersection comparator considers * two spans equal if they intersect. If * the search finds a match then we have an * intersection.
*/ int found = Collections.binarySearch(mSpans, new Span(start, end),
SpanIntersection.instance);
doesIntersect = found >= 0;
/* The addInfinite() method has been invoked so * everything intersect this instance.
*/
} else {
doesIntersect = true;
}
return doesIntersect;
}
/** * Sort the spans in ascending order by their * start position. After the spans are sorted * collapse any spans that intersect into a * single span. The result is a sorted, * non-overlapping list of spans.
*/ privatevoid sortAndCollapse() {
Collections.sort(mSpans);
mAddsSinceSort = 0;
Iterator<Span> iter = mSpans.iterator();
/* Have 'span' start at the first span in * the collection. The collection may be empty * so we're careful.
*/
Span span = null; if (iter.hasNext()) {
span = iter.next();
}
/* Loop over the spans collapsing those that intersect * into a single span.
*/ while (iter.hasNext()) {
Span nextSpan = iter.next();
/* The spans are in ascending start position * order and so the next span's starting point * is either in the span we are trying to grow * or it is beyond the first span and thus the * two spans do not intersect. * * span: <----------< * nextSpan: <------ (intersects) * nextSpan: <------ (doesn't intersect) * * If the spans intersect then we'll remove * nextSpan from the list. If nextSpan's * ending was beyond the first's then * we extend the first. * * span: <----------< * nextSpan: <-----< (don't change span) * nextSpan: <-----------< (grow span)
*/
if (span.subsume(nextSpan)) {
iter.remove();
/* The next span did not intersect the current * span and so it can not be collapsed. Instead * it becomes the start of the next set of spans * to be collapsed.
*/
} else {
span = nextSpan;
}
}
}
/* // For debugging.
private void printSpans() { System.out.println("----------"); if (mSpans != null) { Iterator<Span> iter = mSpans.iterator(); while (iter.hasNext()) { Span span = iter.next(); System.out.println(span); } } System.out.println("----------");
}
*/
/** * Holds a single half-open interval.
*/ staticclass Span implements Comparable<Span> {
/** * The span includes the starting point.
*/ privatefloat mStart;
/** * The span goes up to but does not include * the ending point.
*/ privatefloat mEnd;
/** * Create a half-open interval including * {@code start} but not including * {@code end}.
*/
Span(float start, float end) {
mStart = start;
mEnd = end;
}
/** * Return the start of the {@code Span}. * The start is considered part of the * half-open interval.
*/ finalfloat getStart() { return mStart;
}
/** * Return the end of the {@code Span}. * The end is not considered part of the * half-open interval.
*/ finalfloat getEnd() { return mEnd;
}
/** * Change the initial position of the * {@code Span}.
*/ finalvoid setStart(float start) {
mStart = start;
}
/** * Change the terminal position of the * {@code Span}.
*/ finalvoid setEnd(float end) {
mEnd = end;
}
/** * Attempt to alter this {@code Span} * to include {@code otherSpan} without * altering this span's starting position. * If {@code otherSpan} can be so consumed * by this {@code Span} then {@code true} * is returned.
*/ boolean subsume(Span otherSpan) {
/* We can only subsume 'otherSpan' if * its starting position lies in our * interval.
*/ boolean isSubsumed = contains(otherSpan.mStart);
/* If the other span's starting position * was in our interval and the other span * was longer than this span, then we need * to grow this span to cover the difference.
*/ if (isSubsumed && otherSpan.mEnd > mEnd) {
mEnd = otherSpan.mEnd;
}
return isSubsumed;
}
/** * Return true if the passed in position * lies in the half-open interval defined * by this {@code Span}.
*/ boolean contains(float pos) { return mStart <= pos && pos < mEnd;
}
/** * Rank spans according to their starting * position. The end position is ignored * in this ranking.
*/
@Override publicint compareTo(Span otherSpan) { float otherStart = otherSpan.getStart(); int result;
if (mStart < otherStart) {
result = -1;
} elseif (mStart > otherStart) {
result = 1;
} else {
result = 0;
}
return result;
}
public String toString() { return"Span: " + mStart + " to " + mEnd;
}
}
/** * This class ranks a pair of {@code Span} * instances. If the instances intersect they * are deemed equal otherwise they are ranked * by their relative position. Use * {@code SpanIntersection.instance} to * get the single instance of this class.
*/ staticclass SpanIntersection implements Comparator<Span> {
/** * This class is a Singleton and the following * is the single instance.
*/ staticfinal SpanIntersection instance = new SpanIntersection();
/** * Only this class can create instances of itself.
*/ private SpanIntersection() {
}
publicint compare(Span span1, Span span2) { int result;
/* Span 1 is entirely to the left of span2. * span1: <-----< * span2: <-----<
*/ if (span1.getEnd() <= span2.getStart()) {
result = -1;
/* Span 2 is entirely to the right of span2. * span1: <-----< * span2: <-----<
*/
} elseif (span1.getStart() >= span2.getEnd()) {
result = 1;
/* Otherwise they intersect and we declare them equal.
*/
} else {
result = 0;
}
return result;
}
}
}
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.