|
Java-API--Dokumentation | ||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object SubArray
public class SubArray
Datentyp, der einen bestimmten (definierbaren) Teil eines Arrays darstellt. Dieser Teil wird Sub-Array genannt.
Ein Sub-Array ist eindeutig definiert durch drei Angaben:
In dieser Klasse wird diese Eindeutigkeit umgesetzt durch interne Speicherung
Alternativ zu Start-Stelle und Laenge des Sub-Arrays waeren natuerlich auch Start-Stelle und End-Stelle ausreichend, um den Sub-Array eindeutig zu definieren. Warum Start und Laenge besser sind als Beginn und Ende, beschrieb E. W. Dijkstra im Jahre 1982 recht anschaulich. [vgl. EWD831] Diese Klasse stellt der Bequemlichkeit halber Methoden zur Verfuegung, die direkt Beginn- und End-Stelle zurueckliefern, so dass eine entsprechende Umrechnung nur beim Setzen der End-Stelle notwendig ist. Diese Umrechnung ist weiter unten erklaert.
Bemerkenswert ist, dass die Summe der Elemente des Sub-Arrays diesen nicht definiert. Vielmehr ist die Summe eine Eigenschaft des Sub-Arrays. Immer, wenn man Start und Laenge des Sub-Arrays kennt, ist das Berechnen der Summe trivial. Aus einer Summe allein kann man aber selbst bei bekanntem Gesamt-Array oft nicht eindeutig auf das zugehoerige Sub-Array schliessen.
Um das Arbeiten mit der Summe zu erleichtern, verfuegt jede
Instanz dieser Klasse ueber einen Cache, der die aktuelle Summe
zwischenspeichert, wann immer sie bekannt ist. Dieser Cache bleibt
bis zur naechsten Aenderung der Definition des Sub-Arrays gueltig.
Die Objektmethoden setSum(int)
und getSum()
erlauben den direkten Zugruff auf den Cache. Falls beim Aufruf von
getSum()
der Cache gerade veraltet ist, wird die Summe
automatisch mit einer Schleife neu berechnet und der Cache aktualisiert.
Beim Arbeiten mit dieser Klassse wird man in der Regel zunaechst mit
einem Konstruktor und dem new
-Operator eine neue Instanz,
also ein neues Objekt vom Typ SubArray, erstellen. Auf diesem Objekt
wird man dann je nach Bedarf Objektmethoden aufrufen (das sind die
ohne static
),
z. B. variablenname.print();
.
Eine interessante Anwendung dieser Klasse besteht darin, den
Rueckgabe-Typ einer Methode als SubArray
zu definieren.
Dadurch wird es moeglich, statt etwa einer einzigen Zahl mehrere
Zahlen zuruckzugeben -- naemlich genau diejenigen Zahlen, durch
die ein Sub-Array definiert wird.
Abgesehen von den Objektmethoden stehen auch einige Klassenmethoden zum
Aufruf zur Verfuegung:
Die Methoden findLeftEdgeMaximum(int[],int,int)
und
findRightEdgeMaximum(int[],int,int)
ermitteln innerhalb des
angegebenen Array-Teils das linke bzw. rechte Randmaximum und geben das
Ergebnis als Objekt vom Typ SubArray
zurueck. Das kann
nuetzlich sein bei Divide-and-Conquer--Algorithmen mit Sub-Arrays.
Beispiel. Die folgende Klasse ermittelt die rechte Haelfte
eines an der Kommandozeile eingegebenen Arrays und zeigt ihre Lage
im Gesamt-Array an:
public class RechteHaelfteFinder {
public SubArray findeRechteHaelfte (int[] array) {
// rechte Haelfte ermitteln:
int mitte = array.length / 2;
int startRechteHaelfte = mitte;
int laengeRechteHaelfte = array.length - mitte;
// SubArray-Objekt konstruieren und zurueckgeben:
SubArray ergebnis = new SubArray(array);
ergebnis.setStart(startRechteHaelfte);
ergebnis.setLength(laengeRechteHaelfte);
return ergebnis;
}
public static void main (String[] args) {
int[] eingabeArray = SubArray.parseStringArray(args);
// weil die Methode findeRechteHaelfte(int[]) eine
// Objektmethode ist (nicht static!), muessen wir
// erst ein neues Objekt konstruieren:
RechteHaelfteFinder finder = new RechteHaelfteFinder();
SubArray rechteHaelfte;
rechteHaelfte = finder.findeRechteHaelfte(eingabeArray);
rechteHaelfte.print();
}
}
Beim Aufruf von der Kommandozeile mit
java RechteHaelfteFinder 1 2 3 4 5 6
wird folgendes Ergebnis ausgegeben:
1 2 3 [4 5 6]
Hinweis. Soll ein Sub-Array subArray
anhand der
Indizes des ersten und letzten Elements (beginIndex
respektive endIndex
) definiert werden, koennen folgende
Objektmethoden-Aufrufe dazu verwendet werden:
subArray.setStart(beginIndex);
subArray.setLength(endIndex - beginIndex + 1);
(Die + 1
sind dabei notwendig, denn offensichtlich hat
ein Sub-Array, dessen erstes und letztes Element identisch sind
(endIndex == beginIndex
), immer die Laenge eins. Bei einer
einfachen Differenz endIndex - beginIndex
wuerde sich dann
jedoch faelschlich null fuer die Laenge ergeben. Folglich muss diese
Differenz um eins erhoeht werden.)
Warnung. Diese Klasse arbeitet unmittelbar auf dem durch
array
referenzierten Array. Das Verhalten dieser Klasse
bei externer Veraenderung dieses Arrays ist nicht definiert. Um daraus
resultierende Probleme zu umgehen, kann der Array beim Instanziieren
dieser Klasse dupliziert werden:
int[] array = new int[] {1, 2, 3};
SubArray subArray = new SubArray(array.clone());
Anmerkung. Die ueberschreibbaren Methoden dieser Klasse werden
nicht von anderen Methoden oder Konstruktoren dieser Klasse aufgerufen.
Das bedeutet, dass diese Klasse durch Vererbung erweitert werden kann.
Constructor Summary | |
---|---|
SubArray(int[] array)
Konstruktor; erstellt ein neues SubArray-Objekt fuer den ganzen uebergebenen Array. |
|
SubArray(int[] array,
int subArrayStart,
int subArrayLength)
Konstruktor; erstellt ein neues SubArray-Objekt mit bestimmten Grenzen. |
|
SubArray(SubArray array,
int beginIndex,
int endIndex)
Konstruktor; erstellt eine Kopie der uebergebenen SubArray-Instanz mit veraenderten Sub-Array--Grenzen. |
Method Summary | |
---|---|
protected Object |
clone()
Erstellt eine exakte Bitkopie dieses SubArray-Objekts, einschliesslich des Inhalts des Gesamt-Arrays. |
int |
compareTo(Object o)
Vergleicht dieses Objekt mit dem angegebenen Objekt. |
boolean |
equals(Object obj)
Prueft, ob ein anderes Objekt gleich diesem ist. |
void |
findLeftEdgeMaximum()
Errechnet das linke Randmaximum dieses Sub-Arrays. |
static SubArray |
findLeftEdgeMaximum(int[] array,
int beginIndex,
int endIndex)
Errechnet das linke Randmaximum eines Arrays-Teils. |
void |
findRightEdgeMaximum()
Errechnet das rechte Randmaximum dieses Sub-Arrays. |
static SubArray |
findRightEdgeMaximum(int[] array,
int beginIndex,
int endIndex)
Errechnet das rechte Randmaximum eines Arrays-Teils. |
int |
getBeginIndex()
Liefert den auf den Gesamt-Array bezogenen Index des ersten Elements des Sub-Arrays. |
int |
getEndIndex()
Liefert den auf den Gesamt-Array bezogenen Index des letzten Elements des Sub-Arrays. |
(package private) int[] |
getFullArray()
Zugriffsmethode; liefert den bei der Instanziierung gesetzten Gesamt-Array. |
int |
getLength()
Zugriffsmethode; liefert die Laenge des Sub-Arrays. |
int |
getStart()
Zugriffsmethode; liefert den Index des Beginns des Sub-Arrays. |
int |
getSum()
Liefert die Summe aller Elemente des Sub-Arrays in seinen derzeitigen Grenzen. |
int |
hashCode()
Liefert den Hash-Code fuer diesen Sub-Array. |
void |
print()
Gibt eine String-Repraesentation dieses Objekts auf dem Standard-Ausgabe-Stream aus. |
void |
setLength(int subArrayLength)
Zugriffsmethode; setzt die Laenge des Sub-Arrays. |
void |
setStart(int subArrayStart)
Zugriffsmethode; setzt den Index des Beginns des Sub-Arrays. |
void |
setSum(int subArraySum)
Setzt den Cache der Summe des Sub-Arrays. |
int[] |
toArray()
Kopiert den Sub-Array in einen neu angelegten Integer-Array. |
String |
toString()
Liefert eine String-Repraesentation dieses Objekts. |
Methods inherited from class java.lang.Object |
---|
finalize, getClass, notify, notifyAll, wait, wait, wait |
Constructor Detail |
---|
public SubArray(int[] array)
SubArray subArray = new SubArray(array);
subArray.setStart(0);
subArray.setLength(array.length);
Der Gesamt-Array kann in dieser Instanz nicht veraendert werden; noetigenfalls ist eine neue Instanz dieser Klasse mit einem anderen Array zu erstellen.
Beispiel:
int[] array = {1, 2, 3};
SubArray subArray = new SubArray(array);
System.out.println(subArray); // [1 2 3]
array
- der Gesamt-Array fuer die neue Instanz
NullPointerException
- falls array == null
setStart(int)
,
setLength(int)
public SubArray(int[] array, int subArrayStart, int subArrayLength)
SubArray subArray = new SubArray(array);
subArray.setStart(subArrayStart);
subArray.setLength(subArrayLength);
Der Gesamt-Array kann in dieser Instanz nicht veraendert werden; noetigenfalls ist eine neue Instanz dieser Klasse mit einem anderen Array zu erstellen.
Beispiel:
int[] array = {1, 2, 3};
SubArray subArray = new SubArray(array, 1, 1);
System.out.println(subArray); // 1 [2] 3
array
- der Gesamt-Array fuer die neue InstanzsubArrayStart
- der Index des Beginns des Sub-ArrayssubArrayLength
- die Laenge des Sub-Arrays
NullPointerException
- falls array == null
setStart(int)
,
setLength(int)
public SubArray(SubArray array, int beginIndex, int endIndex)
SubArray subArray = new SubArray(array.getFullArray());
subArray.setStart(beginIndex);
subArray.setLength(endIndex - BeginIndex + 1);
Im Gegensatz zu den meisten anderen Konstruktoren und Methoden
werden hier Indizes auf den Gesamt-Array als Parameter
gefordert. Die Indizes zaehlen dabei einschliesslich, so dass im
Falle beginIndex == endIndex
der neue Sub-Array die
Laenge 1 hat.
Der Gesamt-Array kann in dieser Instanz nicht veraendert werden; noetigenfalls ist eine neue Instanz dieser Klasse mit einem anderen Array zu erstellen.
Beispiel. In diesem Code-Schnipsel wird
array2
als exakte Kopie von array1
erstellt:
SubArray original = ...; // beliebiger Sub-Array
int beginIndex = original.getStart();
int endIndex = original.getStart() + original.getLength() - 1;
SubArray kopie = new SubArray(original, beginIndex, endIndex);
System.out.println(kopie.equals(original)); // true
array
- der Gesamt-Array fuer die neue InstanzbeginIndex
- der Index des ersten Elements im neuen
Sub-ArrayendIndex
- der Index des letzten Elements im neuen
Sub-Array
NullPointerException
- falls array == null
setStart(int)
,
setLength(int)
Method Detail |
---|
int[] getFullArray()
public void setStart(int subArrayStart)
Beispiel:
int[] array = new int[] {1, 2, 3};
SubArray subArray = new SubArray(array, 1, 1);
System.out.println(subArray); // 1 [2] 3
subArray.setStart(0);
System.out.println(subArray); // [1] 2 3
Beim Aufruf dieser Methode wird der interne Cache der
Sub-Array--Summe als veraltet markiert. Ein anschliessender
Aufruf von getSum()
fuehrt zu einer Neuberechnung
der Sub-Array--Summe.
subArrayStart
- auf den Gesamt-Array bezogener Array-Index,
an dem der Sub-Array beginnen sollgetSum()
public int getStart()
Der zurueckgegebene Index ist so angepasst, dass sich immer eine gueltige Definition des Sub-Arrays ergibt.
Beispiel:
Wenn
System.out.println(subArray)
die Ausgabe "1 2 3 [4 5] 6
" erzeugt, hat
subArray.getStart()
genau den Wert
3
.
getLength()
public void setLength(int subArrayLength)
Beispiel:
int[] array = new int[] {1, 2, 3};
SubArray subArray = new SubArray(array, 1, 1);
System.out.println(subArray); // 1 [2] 3
subArray.setLength(2);
System.out.println(subArray); // 1 [2 3]
Beim Aufruf dieser Methode wird der interne Cache der
Sub-Array--Summe als veraltet markiert. Ein anschliessender
Aufruf von getSum()
fuehrt zu einer Neuberechnung
der Sub-Array--Summe.
subArrayLength
- Laenge des Sub-ArraysgetSum()
public int getLength()
Die zurueckgegebene Laenge ist so angepasst, dass sich immer eine gueltige Definition des Sub-Arrays ergibt.
Beispiel:
Wenn
System.out.println(subArray)
die Ausgabe "1 2 3 [4 5] 6
" erzeugt, hat
subArray.getLength()
genau den Wert
2
.
getStart()
public void setSum(int subArraySum)
Diese Methode kann bei bereits bekannter Summe aufgerufen
werden, um den internen Cache der Summe aufzufrischen. Beim
naechsten Aufruf von getSum()
wird direkt der
dieser Methode uebergebene Wert zurueckgeliefert, eine
Neuberechnung der Sub-Array--Summe findet dann nicht statt.
subArraySum
- Summe des Sub-ArraysgetSum()
public int getSum()
Um Rechenzeit zu sparen, wird nach Moeglichkeit der interne Cache der Summe verwendet. Ist der Cache jedoch nicht mehr frisch, muss die Summe neu berechnet werden. Dies geschieht mittels einer Iteration mit O(n)-Komplexitaet.
Diese Methoden frischen den Cache auf:
setSum(int)
getSum()
findLeftEdgeMaximum()
findRightEdgeMaximum()
Diese Methoden markieren den Cache als veraltet:
setStart(int)
setLength(int)
Beispiel:
int[] array = new int[] {1, 2, 3};
SubArray subArray = new SubArray(array, 1, 2);
System.out.println(subArray); // 1 [2 3]
System.out.println(subArray.getSum()); // 5
setSum(int)
public int getBeginIndex()
subArray.getBeginIndex()
entspricht genau:
subArray.getStart()
Diese Methode ist nur ein Alias fuer die Methode
getStart()
. Sie stellt das Gegenstueck zu
getEndIndex()
dar.
getStart()
public int getEndIndex()
subArray.getEndIndex()
entspricht genau:
subArray.getStart() + subArray.getLength() - 1
public void findLeftEdgeMaximum()
Das zurueckgegebene Objekt hat einen erfrischten Cache der Sub-Array--Summe.
Beispiel:
int[] array = new int[] {1, -4, 2};
SubArray subArray = new SubArray(array);
System.out.println(subArray); // [1 -4 2]
subArray.findLeftEdgeMaximum();
System.out.println(subArray); // [1] -4 2
setSum(int)
public void findRightEdgeMaximum()
Das zurueckgegebene Objekt hat einen erfrischten Cache der Sub-Array--Summe.
Beispiel:
int[] array = new int[] {1, -4, 2};
SubArray subArray = new SubArray(array);
System.out.println(subArray); // [1 -4 2]
subArray.findRightEdgeMaximum();
System.out.println(subArray); // 1 -4 [2]
setSum(int)
public static SubArray findLeftEdgeMaximum(int[] array, int beginIndex, int endIndex)
array
den Index beginIndex
hat und dessen Summe der
Elemente so gross wie moeglich ist.
Das zurueckgegebene Objekt hat einen erfrischten Cache der Sub-Array--Summe.
Beispiel:
int[] array = new int[] {1, -4, 2};
SubArray subArray = SubArray.findLeftEdgeMaximum(array, 0, 2);
System.out.println(subArray); // [1] -4 2
array
- der Array, in dem sich der Array-Teil befindet,
von dem das Randmaximum zu ermitteln istbeginIndex
- der Index des ersten Elements des Array-TeilsendIndex
- der Index des letzten Elements des Array-Teils
findLeftEdgeMaximum()
,
setSum(int)
public static SubArray findRightEdgeMaximum(int[] array, int beginIndex, int endIndex)
array
den Index endIndex
hat und
dessen Summe der Elemente so gross wie moeglich ist.
Das zurueckgegebene Objekt hat einen erfrischten Cache der Sub-Array--Summe.
Beispiel:
int[] array = new int[] {1, -4, 2};
SubArray subArray = SubArray.findRightEdgeMaximum(array, 0, 2);
System.out.println(subArray); // 1 -4 [2]
array
- der Array, in dem sich der Array-Teil befindet,
von dem das Randmaximum zu ermitteln istbeginIndex
- der Index des ersten Elements des Array-TeilsendIndex
- der Index des letzten Elements des Array-Teils
findRightEdgeMaximum()
,
setSum(int)
public void print()
Beispiel:
int[] array = new int[] {1, 2, 3};
SubArray subArray = new SubArray(array);
subArray.print(); // [1 2 3]
Im vorstehenden Beispiel koennte man anstelle von
subArray.print();
genau so gut auch
System.out.println(subArray);
schreiben. Diese
beiden Schreibweisen sind genau gleichbedeutend.
toString()
,
PrintStream.println(Object)
public String toString()
toString
in class Object
public int[] toArray()
protected Object clone() throws CloneNotSupportedException
clone
in class Object
SubArray
CloneNotSupportedException
- falls die
runtime class dieses Objekts nicht
Cloneable
implementiertObject.clone()
,
Cloneable
public int compareTo(Object o)
Hinweis: Diese Klasse hat eine natuerliche Ordnung, die nicht mit equals uebereinstimmt.
compareTo
in interface Comparable
o
- das zu vergleichende Objekt
o
NullPointerException
- falls o == null
ClassCastException
- falls o
kein Sub-Array
ist
ConcurrentModificationException
- falls die
beiden Sub-Arrays ungleiche Gesamt-Arrays habenpublic boolean equals(Object obj)
equals
in class Object
obj
- das auf Gleichheit zu pruefende Objekt
true
, falls obj
gleich diesem
Objekt istpublic int hashCode()
hashCode
in class Object
Object.hashCode()
|
Java-API--Dokumentation | ||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |