MezData-Logo Creative Commons License 475 Lösungen Button :PI-BLUEJ: Felder und Schleifen

Zweierpotenzen

Beim Zahlenratenprojekt konnte nur eine Zahl gemerkt werden. Eine Klasse Zweierpotenzen soll die Zweierpotenzen von 20 bis 28 ausgeben können. Die Liste der Zweierpotenzen ist als Klassenattribut (static) ausgeführt - es muss kein Objekt erzeugt werden. Mittels Inspect kann die Speicherstruktur betrachtet werden. [Zweierpotenzen.java]

Zweierpotenzen
zweiHoch[]:GZ = {1,2,4,8,16,32,64,128,256}
ausgebenZweierpotenz(n:GZ)
public class Zweierpotenzen{
  static int zweiHoch[] = {1,2,4,8,16,32,64,128,256};
  static void ausgebenZweierpotenz(int n){
    System.out.println("2 hoch "+n+" = "+zweiHoch[n]);
  }
}

 Merker Klasse

Es sollen mehrere Zahlen gespeichert werden können.

Merker
zahl[] : GZ
eFindex: GZ
merke(n:GZ)
public class Merker{
  int[] zahl;  // Listenspeicher
  int eFindex; // erster freier Index
  
  void merke(int n){
    
  }
}
int[] zahl = new int[3]; // Listenspeicher

void merke(int n){
  if (eFindex < zahl.length)
    zahl[eFindex++]=n;
  else
    System.out.println("Die Liste ist voll: "+eFindex);
}

Inspiziert man nun ein Merker-Objekt, zeigt sich:

Mit int[] zahl wird ein Verweis auf eine Int-Liste definiert, null bedeutet, dass der Verweis ins Nichts zeigt,
es ist noch keine Liste angelegt.
Mit int[] zahl = new int [3] wird dem Verweis eine neues Int-Listenobjekt mit drei Speicherplätzen zugewiesen:
Die Anzahl der Speicherplätze wird in dem Attribut length abrufbar: zahl.length ergibt hier den Wert 3

Entwickeln Sie den Quellcode für die Methode merke(int n). Verhindern Sie, daß ein Laufzeitfehler auftritt, wenn die Liste voll wird..

 Ausgeben der ganzen Liste auf Konsole mit While-Schleife

Der Inhalt des ganzen Zahlenfeldes soll auf der Konsole ausgegeben werden, eine Methode ausgeben() wird entwickelt:

void ausgeben(){
  int i = 0;  // i mit 0 initialisieren
  while (i<zahl.length){ // solange Liste noch nicht zu Ende
    System.out.println("zahl["+i+"]="+zahl[i]);  // Ausgeben der Zahl
    i++; // weiter in der Liste
  }
}

Erweitern Sie die Methode so, daß die Ausgabe bei der ersten Null in zahl[i] stoppt. Erstellen Sie ein Struktogramm.

 Erweitern des Speichers, kopieren mit For-Schleife (Zählschleife)

Der Zahlenspeicher soll verdoppelt werden, bei einfachen Int-Listen ist eine nachträgliche Erweiterung der Speicherkapazität nicht vorgesehen.
Daher wird zunächst eine neue grössere Liste erzeugt und dann der Inhalt der alten Liste hineinkopiert. Schließlich wird der zahl-Verweis auf die neue Liste gesetzt.

Für das Kopieren müssen schlicht die Indizies der beiden Listen durchgezählt werden:

für i von 0 bis zahl.length-1 kopiere neu[i] <- zahl[i]

Genau dafür ist die For-Schleife gedacht:

void verdoppleSpeicher(){
  int[] neu = new int[zahl.length*2]; // neue Liste erzeugen
  int i;
  for (i=0;i<zahl.length;i++) // in neue Liste kopieren
    neu[i]=zahl[i];
  zahl=neu;  // Verweis nun auf neue Liste
}

Implementieren und Testen Sie die Methode verdoppleSpeicher().

Entwickeln Sie eine Methode verdoppleSpeicher2(), die mit einer While- statt mit einer For-Schleife die Daten kopiert.

Erweitern Sie die Methode merke() mit der Speicherverdopplung. Lösung..