Algorithmus entwickeln

Kirby.exe

Top Contributor
Also wir sollen das Knobel Spiel "Die Türme von Hanoi" programmieren. Dazu sollen wir einmal eine Datenstruktur und einen rekursiven Algorithmus entwickeln. Die Datenstruktur habe ich fertig:

Java:
public class HanoiTurm{
      // jede Scheibe wird durch einen String dargestellt
      // je laenger ein String, desto groesser die Scheibe
      // in values werden somit die Scheiben abgelegt
      private String[] values;
      // position gibt die Position der obersten Scheibe an
      private int position;
      /**
       * Konstruktor (keine Scheibe vorhanden, Stabgroesse ist 1)
       **/
      public HanoiTurm(){   
            position = -1;
            values = new String[1];
      }   
      /**
       * Konstruktor (keine Scheibe vorhanden)
       * @param groesse gibt die Groesse des Stabes an (und somit
       * wie viele Scheiben maximal auf diesen gelegt werden koennen)
       **/
      
      public HanoiTurm(int groesse){   
            position = -1;
            values = new String[groesse];
      }
      /**
       * Gibt die maximale Anzahl an Scheiben auf dem Stab zurueck.
       * @return die max. Anzahl an Scheiben
       **/
      public int maxSize(){
          return values.length;
      }
      
      public String top() {
          if(values[position] != null) {
              return values[position];
          }else {
              System.out.println("Zugriff auf leeren Stab");
          }
          return "null";
      }
      
      public void pop() {
          if(values[position] != null) {
              values[position] = null;
              position -= 1;
          }else {
              System.out.println("Zugriff auf leeren Stab");
          }
      }
      
      public void push(String input) {
          if(position+1 > maxSize()) {
              System.out.println("Maximale Anzahl an Scheiben erreicht");
          }else if((position+1 <= maxSize())&&(values[position].length() < input.length())) {
              System.out.println("Kleinere Scheibe vorhanden");
          }else {
              position++;
              values[position] = input;
          }
      }
      
      public int size() {
          return (position+1);
      }
}

Jedoch bin ich mehr als verwirrt wie ich mit dem Algorithmus anfangen soll :(
Hier ist die Aufgabenstellung für den Algorithmus:

12904
 

Kirby.exe

Top Contributor
Ok beim mehrfachen lesen, glaube ich ungefähr zu wissen, was ich tun soll...Ich soll meine Datenstruktur verwenden und dass eigentliche Hauptprogramm für das Spiel schreiben
 

Kirby.exe

Top Contributor
Vielleicht verwirre ich mich gerade selber, aber wäre das ein vernünftiger Algorithmus?

Ich hatte mir so etwas überlegt, jedoch erhalte ich einen schönen StackOverflow :( Ich habe massive Schwierigkeiten mich in rekursive Programmierung hineinzudenken :(

Hier der Ansatz:

Java:
public class TuermeVonHanoi{
    static int zug;
  
    public static void main(String[] args){
        zug = 0;
        TuermeVonHanoi s = new TuermeVonHanoi();
        HanoiTurm vonTurm = new HanoiTurm();
        HanoiTurm nachTurm = new HanoiTurm();
        HanoiTurm lagerTurm = new HanoiTurm();
        for(int i = 0; i < args.length; i++){
           s.bewege(args[i], vonTurm, nachTurm, lagerTurm);
        }
    }
  
    public void bewege(String scheibe, HanoiTurm vonTurm, HanoiTurm nachTurm, HanoiTurm lagerTurm) {
        if(scheibe.length() > 0 && nachTurm.top().length() >= scheibe.length()) {
            bewege(scheibe, vonTurm, lagerTurm, nachTurm);
            System.out.print("Scheibe "+ scheibe);
            System.out.print(" von "+ vonTurm);
            System.out.println(" nach "+ nachTurm);
            zug=zug+1;
            bewege(scheibe,lagerTurm,nachTurm,vonTurm);
        }
    }
}

Ich hätte es nämlich am liebsten so gemacht, jedoch ist dies keine Rekursion:
Java:
if(scheibe.length() > 0) {
            if(nachTurm.top().equals("null")) {
                String temp = vonTurm.top();
                vonTurm.pop(); // Das obere Objekt entfernen
                nachTurm.push(temp);
            }else if(nachTurm.top().length() < vonTurm.top().length()) {
                System.out.println("Das ist nicht erlaubt, die Scheibe auf dem Turm ist zu klein!");
            }else {
                String temp = vonTurm.top();
                vonTurm.pop(); // Das obere Objekt entfernen
                nachTurm.push(temp);
            }
        }else {
            System.out.println("Die Scheibe ist zu klein für das Spiel!");
        }
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Vielleicht verwirre ich mich gerade selber, aber wäre das ein vernünftiger Algorithmus?
Nein. Als erstes bekommst Du als Parameter über die Kommandozeile die Anzahl der Scheiben angegeben, d. h. den String solltest Du erstmal in eine Zahl umwandeln.

Dann ändert sich Deine Methode zu:
Java:
void bewege(int scheiben, HanoiTurm vonTurm, HanoiTurm nachTurm, HanoiTurm lagerTurm)
Die Überlegung ist die folgende: um die n-te Scheibe (von oben) eines Von-Turms auf einen Zielturm legen zu können, müssen zuvor (n-1)-Scheiben des Von-Turms auf den Lagerturm verschoben werden. Dann kann die n-te Scheibe auf den Zielturm gelegt werden. Anschließend können die (n-1)-Scheiben des Lagerturms auf den Zieltrum verschoben werden. Vgl. https://de.wikipedia.org/wiki/Türme_von_Hanoi#Rekursiver_Algorithmus
 

Kirby.exe

Top Contributor
Nein. Als erstes bekommst Du als Parameter über die Kommandozeile die Anzahl der Scheiben angegeben, d. h. den String solltest Du erstmal in eine Zahl umwandeln.

Dann ändert sich Deine Methode zu:
Java:
void bewege(int scheiben, HanoiTurm vonTurm, HanoiTurm nachTurm, HanoiTurm lagerTurm)
Die Überlegung ist die folgende: um die n-te Scheibe (von oben) eines Von-Turms auf einen Zielturm legen zu können, müssen zuvor (n-1)-Scheiben des Von-Turms auf den Lagerturm verschoben werden. Dann kann die n-te Scheibe auf den Zielturm gelegt werden. Anschließend können die (n-1)-Scheiben des Lagerturms auf den Zieltrum verschoben werden. Vgl. https://de.wikipedia.org/wiki/Türme_von_Hanoi#Rekursiver_Algorithmus
Achsooo ich glaube ich habe mich sehr sehr seeeeeeehr verwirrt xD Ich dachte die per Kommandozeilenparameter übergebenden Werte sind Scheiben als Strings :) Jetzt macht das auch Sinn xD Ich dachte mir die ganze Zeit wie soll ich das bitte machen xD
 

LimDul

Top Contributor
Der Code ist nicht korrekt :) Mittels \ wird ein Zeichen escaped. Wenn du (wie du vermutlich möchtest) wirklich einen Backslash im String haben willst, musst du \\ schreiben.
 
X

Xyz1

Gast
Ab compliance level Java 13 sollte eigentlich auch System.out.println(`/\`); funktionieren (wenn "preview features" aktiviert sind)...
Bei mir zickt Eclipse aber herum
 

Kirby.exe

Top Contributor
Ich glaube ich brauche nochmal Hilfe für den print...Also sagen wir ich haben n Scheiben und ich möchte die vernünftig formatiert haben, wie mache ich dass?

Das ist mein momentaner Output:

Java:
3 Scheiben, 7 Verschiebungen
/\
/\/\
/\/\/\

Gewünschter Output:

Java:
3 Scheiben, 7 Verschiebungen
  /\
 /\/\
/\/\/\
 

LimDul

Top Contributor
Du musst halt links so viele Leerzeichen hinzufügen wie nötig.

- Pro Zeile kommt links & rechts ein Zeichen hinzu
- Das heißt, wenn du drei Zeilen heißt (3 scheiben) musst du in der ersten Zeile links und rechts je 2 Leerzeichen ergänzen. In der zweiten Zeile jeweils 1, in der dritten keins.
- Bei 10 Scheiben wären es in der ersten Zeile 9 Leerzeichen usw.
 

Kirby.exe

Top Contributor
Also ich habe die Aufgabe mehr oder weniger gelöst...Das Problem ist es werden zwei Test durchgeführt:
- einmal wird der rekursive Algorithmus getestet(ohne Error Prints)
- und einmal wird die Datenstruktur getestet(mit Error Prints)

Mein Problem ist, wie soll ich das hinbekommen, dass die Error Prints beim ersten Test nicht ausgegeben werden, ohne dass ich etwas Importe oder den OutputStream manipuliere?

Hier sind die Klassen:
Java:
public class HanoiTurm{
      // jede Scheibe wird durch einen String dargestellt
      // je laenger ein String, desto groesser die Scheibe
      // in values werden somit die Scheiben abgelegt
      private String[] values;
      // position gibt die Position der obersten Scheibe an
      private int position;
      /**
       * Konstruktor (keine Scheibe vorhanden, Stabgroesse ist 1)
       **/
      public HanoiTurm(){  
            position = -1;
            values = new String[1];
      }  
      /**
       * Konstruktor (keine Scheibe vorhanden)
       * @param groesse gibt die Groesse des Stabes an (und somit
       * wie viele Scheiben maximal auf diesen gelegt werden koennen)
       **/
     
      public HanoiTurm(int groesse){  
            position = -1;
            values = new String[groesse];
      }
      /**
       * Gibt die maximale Anzahl an Scheiben auf dem Stab zurueck.
       * @return die max. Anzahl an Scheiben
       **/
      public int maxSize(){
          return values.length;
      }
     
      public String top() {
          if(position == -1){ position = 0; }
          if(position == 0 && values[position] == null) {
              System.out.println("Zugriff auf leeren Stab");
          }else if(values[position-1] != null) {
              return values[position-1];
          }else {
              System.out.println("Zugriff auf leeren Stab");
          }
          return null;
      }
     
      public void pop() {
          if(position == -1){ position = 0; }
          if(position == 0 && values[position] == null) {
              System.out.println("Zugriff auf leeren Stab");
          }else if(values[position-1] != null) {
              values[position-1] = null;
              position -= 1;
          }else {
              System.out.println("Zugriff auf leeren Stab");
          }
      }
     
      public void push(String input) {
          if(position <= 0){
              position = 0;
              values[position] = input;
              position++;
          }else if((position+1) > maxSize()) {
              System.out.println("maximale Anzahl an Scheiben erreicht");
              return;
          }else if((values[position-1] != null) && (values[position-1].length() < input.length())) {
              System.out.println("kleinere Scheibe vorhanden");
          }else {
               values[position] = input;
               position++;
          }
      }
     
      public int size() {
          if(position == -1){
              return 0;
          }
          return position;
      }
}
Java:
public class TuermeVonHanoi{
    static int zug;
    static int scheibenZahl;
   
    public static void main(String[] args){
        zug = 0;
        scheibenZahl = Integer.parseInt(args[0]);
        TuermeVonHanoi s = new TuermeVonHanoi();
        HanoiTurm vonTurm = new HanoiTurm(scheibenZahl);
        HanoiTurm nachTurm = new HanoiTurm(scheibenZahl);
        HanoiTurm lagerTurm = new HanoiTurm(scheibenZahl);
        for(int i = scheibenZahl; i > 0; i--){
            String tmp = "";
            for(int j = 0; j < i; j++){
                tmp += "a";
            }
            vonTurm.push(tmp);
        }
        s.bewege(scheibenZahl, vonTurm, nachTurm, lagerTurm);
        s.stringify();
    }
   
   public void bewege(int anzahlScheibe, HanoiTurm vonTurm, HanoiTurm nachTurm, HanoiTurm lagerTurm) {
        if (anzahlScheibe > 0){
            bewege(anzahlScheibe-1,vonTurm,lagerTurm,nachTurm);
            String temp = vonTurm.top();
            vonTurm.pop();
            lagerTurm.push(temp);
            zug = zug+1;
            bewege(anzahlScheibe-1,lagerTurm,nachTurm,vonTurm);
        }  
    }
   
    public String leerzeichenCalc(int number) {
        String result = "";
        for(int i = 0; i < scheibenZahl-number; i++) {
            result += " ";
        }
        return result;
    }
   
   
    public void stringify() {
        TuermeVonHanoi s = new TuermeVonHanoi();
        System.out.println(scheibenZahl + " Scheiben, " + zug + " Verschiebungen");
        for(int i = 1; i <= scheibenZahl; i++){
            String result = "";
           for(int j = 0; j < i; j++){
               result += "/\\";
           }
            System.out.println(s.leerzeichenCalc(i) + result);
            result = "";
        }
    }
}
Java:
import java.io.*;
public class TestHanoi {
    public static void main(String[] args) throws IOException {
        if(args.length == 1)
            testeTuermeVonHanoi(args);
        else
            testeHanoiTurm();
    }
    public static void testeHanoiTurm() throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        HanoiTurm stab = new HanoiTurm(Integer.parseInt(in.readLine()));
        String eingabe;
        while(!(eingabe = in.readLine()).equals("")) {
            switch(eingabe) {
                case "top":
                    System.out.println(stab.top());
                    break;
                case "pop":
                    stab.pop();
                    break;
                case "push":
                    stab.push(in.readLine());
                    break;
                case "size":
                    System.out.println(stab.size());
                    break;
            }
        }
    }
    public static void testeTuermeVonHanoi(String[] kommandozeilenparameter) {
        TuermeVonHanoi.main(kommandozeilenparameter);
    }
}

Hier sind die Test Parameter:

Code:
Erwarteter Output:

4 Scheiben, 15 Verschiebungen
   /\
  /\/\
/\/\/\
/\/\/\/\
Code:
Erwarteter Output:

22 Scheiben, 4194303 Verschiebungen
                     /\
                    /\/\
                   /\/\/\
                  /\/\/\/\
                 /\/\/\/\/\
                /\/\/\/\/\/\
               /\/\/\/\/\/\/\
              /\/\/\/\/\/\/\/\
             /\/\/\/\/\/\/\/\/\
            /\/\/\/\/\/\/\/\/\/\
           /\/\/\/\/\/\/\/\/\/\/\
          /\/\/\/\/\/\/\/\/\/\/\/\
         /\/\/\/\/\/\/\/\/\/\/\/\/\
        /\/\/\/\/\/\/\/\/\/\/\/\/\/\
       /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
      /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
     /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
    /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
   /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
  /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

Ich danke euch im voraus schonmal für eure Hilfe :)
 

Kirby.exe

Top Contributor
Ich blicke einfach nicht was ich falsch mache :( Hab zig Millionen out.prints reimgezimmert und finde den Fehler ned :( Ich glaube ich bin blind xD
 
X

Xyz1

Gast
Tipp: public void bewege(int anzahlScheibe, HanoiTurm vonTurm, HanoiTurm nachTurm, HanoiTurm lagerTurm) { ist eine ganz simple rekursive Funktion.
 
K

kneitzel

Gast
Also ich habe nicht ganz Deine Problembeschreibung verstanden, was geht und was nicht geht ... da hast du dich sehr verwirrend ausgedrückt.

Ich wundere mich aber bei deinem Code aber auch massiv über z.B. die Instanzvariable position. Die scheint wenig durchdacht zu sein so dass da gewisse Checks und Aktionen etwas verwirren.

Kannst du den Status / die Bedeutung genau beschreiben? Was bedeutet Position 0 und was die -1?

Und die Checks sind dubios ... wenn position -1 oder 0 ist bei Pop, dann ist position 0. Dubios, aber ok.
Dann Prüfstand du auf position ==0 und value bei position ungleich Null.
=> wenn diese Prüfung so Sinn macht (also die Prüfung auf position gleich 0 nicht ausreichen sollte), dann ist es fatal, dass du im else etwas position - 1 abfragst, denn ein Array wird kein Element mit Index -1 haben...

Daher vermute ich, dass du dir die Zustände nicht sauber überlegt hast und der Code entweder falsch oder schlicht überkompliziert ist.

Du hast einen internen Status, den du kapselst. Da reicht dann die Verwendung von position aus. Dann ist position -1 von mir aus leer und ansonsten ist es der Zeiger auf das oberste Element.
Dann würde aber push eben nur gültige Werte annehmen und position erhöhen. Und top/Pop können sich dann auf einen sauberen Zustand verlassen und nutzen nur die position und müssen nicht mehr prüfen. Aber dann setzt du den Wert von -1 auch nicht einfach auf 0 wenn es -1 ist oder so bei einem Pop oder top ...

Das einfach mal was mir beim Ansehen auf dem Handy aufgefallen ist ... hoffe ich konnte auf dem kleinen Handy die Tippfehler halbwegs klein halten ....
 

Kirby.exe

Top Contributor
Also ich habe nicht ganz Deine Problembeschreibung verstanden, was geht und was nicht geht ... da hast du dich sehr verwirrend ausgedrückt.

Ich wundere mich aber bei deinem Code aber auch massiv über z.B. die Instanzvariable position. Die scheint wenig durchdacht zu sein so dass da gewisse Checks und Aktionen etwas verwirren.

Kannst du den Status / die Bedeutung genau beschreiben? Was bedeutet Position 0 und was die -1?

Und die Checks sind dubios ... wenn position -1 oder 0 ist bei Pop, dann ist position 0. Dubios, aber ok.
Dann Prüfstand du auf position ==0 und value bei position ungleich Null.
=> wenn diese Prüfung so Sinn macht (also die Prüfung auf position gleich 0 nicht ausreichen sollte), dann ist es fatal, dass du im else etwas position - 1 abfragst, denn ein Array wird kein Element mit Index -1 haben...

Daher vermute ich, dass du dir die Zustände nicht sauber überlegt hast und der Code entweder falsch oder schlicht überkompliziert ist.

Du hast einen internen Status, den du kapselst. Da reicht dann die Verwendung von position aus. Dann ist position -1 von mir aus leer und ansonsten ist es der Zeiger auf das oberste Element.
Dann würde aber push eben nur gültige Werte annehmen und position erhöhen. Und top/Pop können sich dann auf einen sauberen Zustand verlassen und nutzen nur die position und müssen nicht mehr prüfen. Aber dann setzt du den Wert von -1 auch nicht einfach auf 0 wenn es -1 ist oder so bei einem Pop oder top ...

Das einfach mal was mir beim Ansehen auf dem Handy aufgefallen ist ... hoffe ich konnte auf dem kleinen Handy die Tippfehler halbwegs klein halten ....
Danke erstmal für deine Antwort:)

Mit dem if(position <= 0){position = 0;} hatte ich versucht die NullPointerExceptions abzufangen etc.
Ich versuche mal meinen Code etwas zu strukturieren :)

Ich könnte natürlich einfach mit 0 im Konstruktur initialisieren, jedoch waren die beiden Konstruktoren vom Dozenten bereits gegeben und da bin ich dann davon ausgegangen, dass er sich wohl etwas dabei gedacht hatte

Ich habe noch eine blöde Frage....:
Ändert sich hierbei der Wert von position?

Java:
 public int size() {
          return position + 1;
      }
Ich glaube nicht, aber ich bin mir nicht sicher...Ich dachte man returned einfach nur einen Wert, welcher sich aus position+1 ergibt.

Edit:

Was mich noch mehr verwirrt ist, wie ich ohne diese Abfrage die Nullpointer umgehe?

Java:
public void push(String input) {
          if(position == -1){ position = 0; } // <---- Ich will das weg, da ich im Else um 1 inkrementiere
          if((position+1) > maxSize()) {
              System.out.println("Maximale Anzahl an Scheiben erreicht");
              return;
          }else if((values[position] != null) && (values[position].length() < input.length())) { // <---- Nur wäre hier dann eine NullpointerException
              System.out.println("Kleinere Scheibe vorhanden");
              System.out.println("Input Scheibe: " + input);
              System.out.println("Vorherige Scheibe: " + top());
          }else {
              position++;
              values[position] = input;
          }
      }
Wenn ich die Abfrage nämlich drinnen lasse, bekomme ich eine OutOfBounds, da er ja inkrementiert und es aber den Index im Array nicht gibt
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also wenn du position +1 hast, dann ändert sich position nicht.

Und Du kannst doch festlegen, was position bedeutet:
-1: leer
0+: höchster Index.

Dann bedeutet top: Du prüfst auf -1 --> Dann ist er leer. Ansonsten gibst Du wert an position zurück.
bei pop: Du prüfst auf -1 -> Dann ist der Stapel leer. Ansonsten Element an stelle position ist die Rückgabe und du reduzierst position um 1.
bei push: Du erhöhst position um 1 und packst das übergebene element an die Stelle position.

Also doch vom Algorithmus her eigentlich ganz einfach, oder?
 

Kirby.exe

Top Contributor
Also wenn du position +1 hast, dann ändert sich position nicht.

Und Du kannst doch festlegen, was position bedeutet:
-1: leer
0+: höchster Index.

Dann bedeutet top: Du prüfst auf -1 --> Dann ist er leer. Ansonsten gibst Du wert an position zurück.
bei pop: Du prüfst auf -1 -> Dann ist der Stapel leer. Ansonsten Element an stelle position ist die Rückgabe und du reduzierst position um 1.
bei push: Du erhöhst position um 1 und packst das übergebene element an die Stelle position.

Also doch vom Algorithmus her eigentlich ganz einfach, oder?
Du hast Recht xD Dankeschön :) Na dann teste ich mal ein bisschen :)
 

Kirby.exe

Top Contributor
Also wenn du position +1 hast, dann ändert sich position nicht.

Und Du kannst doch festlegen, was position bedeutet:
-1: leer
0+: höchster Index.

Dann bedeutet top: Du prüfst auf -1 --> Dann ist er leer. Ansonsten gibst Du wert an position zurück.
bei pop: Du prüfst auf -1 -> Dann ist der Stapel leer. Ansonsten Element an stelle position ist die Rückgabe und du reduzierst position um 1.
bei push: Du erhöhst position um 1 und packst das übergebene element an die Stelle position.

Also doch vom Algorithmus her eigentlich ganz einfach, oder?
Irgendwie stehe ich gerade ganz schön auf dem Schlauch...Ich verstehe nicht ganz wie ich dass umsetzen soll :(
 

Kirby.exe

Top Contributor
Meinst du etwa so?:

Java:
public void pop() {
          if(position == -1){
              System.out.println("Zugriff auf leeren Stab");
          }else if(values[position] != null) {
              values[position] = null;
              position -= 1;
          }
      }
 

Kirby.exe

Top Contributor
Wenn das der Fall ist, verstehe ich das bei top und pop, aber wie mache ich es bei push, dass er auch irgendwann mal inkrementiert?
 

Blender3D

Top Contributor
Die Datenstruktur habe ich fertig:
Ich halte es für keine so gute Idee die Scheiben als Strings zu speichern. Besser ist es die relevanten Daten der Scheiben, die jeweilige Größe zu verwenden.
z.B. Die Scheibe "/\/\" hat die Größe 2. die String lenght() Funktion liefert aber 4.
Aber das ist ja die Vorgabe.
Hier ein Beispiel mit Integer. Die Lösung hilft Dir vielleicht die Probleme bei Deinem Code in den Griff zu bekommen.
Java:
public class start {
    private static int cnt = 0;

    public static void main(String[] args) {
        int size = 22;
        HanoiTower srcTower = new HanoiTower(size);
        HanoiTower tmpTower = new HanoiTower(size);
        HanoiTower destTower = new HanoiTower(size);
        srcTower.fill();
        move(size, srcTower, tmpTower, destTower);
        System.out.println(destTower);
        System.out.println("Scheiben\t: " + size);
        System.out.println("Verschiebungen\t: " + cnt);
    }

    private static void move(int numDisc, HanoiTower srcTower, HanoiTower tmpTower, HanoiTower destTower) {
        if (numDisc <= 0)
            return;
        move(numDisc - 1, srcTower, destTower, tmpTower);
        destTower.push(srcTower.pop());
        cnt++;
        move(numDisc - 1, tmpTower, srcTower, destTower);
    }

}

Java:
public class HanoiTower {
    public final static int EMPTY = -1;
    private int[] discs; // each disc is represented by its size
    private int position; // points to tower's current top position

    /**
     * @param height
     *            Specifies maximum tower's maximum height.
     **/
    public HanoiTower(int height) {
        position = EMPTY;
        discs = new int[height];
    }

    public void fill() {
        position = EMPTY;
        int size = getMaxHeight();
        for (int i = 0; i < getMaxHeight(); i++)
            push(size--);
    }

    private static String getMultipleStr(String str, int num) {
        StringBuffer tmp = new StringBuffer();
        for (int i = 0; i < num; i++)
            tmp.append(str);
        return tmp.toString();
    }

    /**
     * @return Tower's maximum height.
     */
    public int getMaxHeight() {
        return discs.length;
    }

    /**
     * @return Disc's size on towers's top or EMPTY.
     */
    public int top() {
        if (!isEmpty())
            return discs[position];
        System.out.println("Zugriff auf leeren Stab");
        return EMPTY;
    }

    /**
     * Removes disc on tower's top.
     *
     * @return Disc's size on towers's top or EMPTY.
     */
    public int pop() {
        if (isEmpty()) {
            System.out.println("Zugriff auf leeren Stab");
            return EMPTY;
        }
        return discs[position--];
    }

    public boolean isEmpty() {
        return position == EMPTY;
    }

    public boolean isFull() {
        return position == getMaxHeight() - 1;
    }

    /**
     * Puts a disc on tower's top. Provided that new disc is smaller than disc on
     * top and tower isn't full.
     *
     * @param size
     *            Size of new disc.
     * @return true if successful.
     */
    public boolean push(int size) {
        if (isFull()) {
            System.out.println("Maximale Anzahl an Scheiben erreicht");
            return false;
        }
        if (!isEmpty() && (discs[position] < size)) {
            System.out.println("Kleinere Scheibe vorhanden");
            return false;
        }
        discs[++position] = size;
        return true;
    }

    /**
     * @return Tower's height.
     */
    public int height() {
        return position + 1;
    }

    @Override
    public String toString() {
        StringBuffer tmp = new StringBuffer();
        for (int i = position; i >= 0; i--) {
            tmp.append(getMultipleStr(" ", i));
            tmp.append(getMultipleStr("/\\", (discs[i])));
            tmp.append(System.getProperty("line.separator"));
        }
        return tmp.toString();
    }
}
 
K

kneitzel

Gast
Meinst du etwa so?:

Java:
public void pop() {
          if(position == -1){
              System.out.println("Zugriff auf leeren Stab");
          }else if(values[position] != null) {
              values[position] = null;
              position -= 1;
          }
      }

Also der Kernpunkt von meiner Aussage war doch, dass diese Prüfung von wegen if(values[position] != null) nicht gemacht wird.

Jemand, der mit einem Auto fahren möchte: prüft der den "inneren Zustand" des Autos? Du wirst bestimmt hin gehen und vor jedem Schaltvorgang prüfen, ob noch alle Zahnräder im Getriebe da sind. Während der Fahrt könnte ja jemand Dir Zahnräder aus dem Getriebe geklaut haben, also prüfst Du das .... Und ja: Da kann ich dann wirklich verstehen, dass es für dich unmöglich ist, Auto zu fahren.... Und ich fürchte, niemand wird Dir sagen können, wie Du denn das Vorhandensein aller Zahnräder im Getriebe überhaupt prüfen könntest....
Und wie Du es morgens mit dem Auto rechtzeitig in die Uni schaffst, kann ich Dir auch nicht verraten. Das ganze Auto komplett zu zerlegen und wieder zusammen zu setzen, dauert nun einmal.... Und ja: Auch ich kann das nicht - obwohl ich einen Führerschein habe ...
 

Kirby.exe

Top Contributor
Das Problem ist, dass der rekursive Algorithmus trotzdem manchmal versucht z.B. Scheiben auf einen Stab zu pushen und da dort eine kleinere liegt, wird die von mir verfasste Error Meldung geschmissen :( Ich verstehe nicht wie ich das weg kriege... Kann man bestimmte Consolen Ausgaben suppressen ?

So sieht halt die Ausgabe aus:

Code:
Kleinere Scheibe vorhanden
Zugriff auf leeren Stab
Zugriff auf leeren Stab
Kleinere Scheibe vorhanden
Kleinere Scheibe vorhanden
Zugriff auf leeren Stab
Zugriff auf leeren Stab
Kleinere Scheibe vorhanden
Kleinere Scheibe vorhanden
Zugriff auf leeren Stab
Zugriff auf leeren Stab
4 Scheiben, 15 Verschiebungen
   /\
  /\/\
 /\/\/\
/\/\/\/\
 

Kirby.exe

Top Contributor
Also vielleicht bin ich auch einfach nur blind, aber keinen Schimmer wie das gehen soll xD Ich weiß dass man OutPutStreams manipulieren kann, dafür müsste ich das aber Importen und das dürfen wir in dieser Aufgabe nicht...
 
K

kneitzel

Gast
Ja klar. Wenn der Motor komisch Geräusche macht, dann kann man sich auch eine Gegenschall-Ablage einbauen. Dann hörst Du die komischen Geräusche auch nicht mehr.

Sorry, aber wie wäre es, wenn Du den Algorithmus einfach einmal so schreibst, dass er nur Dinge macht, die er machen soll?
Wenn etwas nicht geht und daher eine Fehlermeldung kommt:Frag es vorher ab und mach es erst gar nicht.... (So das vom Algorithmus her nicht eh schon alles klar ist. Ich muss beim Auto auf der Autobahn mit 160km/h weder:
- versuchen den Rückwärtsgang einzulegen (Auch mit Gegenschall-Anlage ist das nicht gut - auch wenn ich nicht mehr höre, was das Getriebe macht.
- Prüfen, ob der Rückwärtsgang eingelegt werden kann. (Aber immer noch besser, als es einfach zu probieren :) )
 

Kirby.exe

Top Contributor
Ja klar. Wenn der Motor komisch Geräusche macht, dann kann man sich auch eine Gegenschall-Ablage einbauen. Dann hörst Du die komischen Geräusche auch nicht mehr.

Sorry, aber wie wäre es, wenn Du den Algorithmus einfach einmal so schreibst, dass er nur Dinge macht, die er machen soll?
Wenn etwas nicht geht und daher eine Fehlermeldung kommt:Frag es vorher ab und mach es erst gar nicht.... (So das vom Algorithmus her nicht eh schon alles klar ist. Ich muss beim Auto auf der Autobahn mit 160km/h weder:
- versuchen den Rückwärtsgang einzulegen (Auch mit Gegenschall-Anlage ist das nicht gut - auch wenn ich nicht mehr höre, was das Getriebe macht.
- Prüfen, ob der Rückwärtsgang eingelegt werden kann. (Aber immer noch besser, als es einfach zu probieren :) )
Ok :) Ich schaue mir meinen rekursiven Algorithmus nochmal auf Papier an :)

P.S. Wer schaltet denn nicht gerne bei 160 KM/H in den Rückwertsgang xD :p
 
X

Xyz1

Gast
Entwickle den Algorithmus schrittweise.
1. Schritt
Java:
	static void hanoi(int index, String von, String nach, String temp) {
		if (index <= 0)
			return;
		hanoi(index - 1, von, temp, nach);
		System.out.println(von + " => " + nach);
		hanoi(index - 1, temp, nach, von);
	}

	public static void main(String[] args) {
		hanoi(3, "a", "b", "c");
	}

2.Schritt
Java:
	static void hanoi(HashMap<String, ArrayDeque<String>> hsd, int index, String von, String nach, String temp) {
		if (index <= 0)
			return;
		hanoi(hsd, index - 1, von, temp, nach);
		String t = hsd.get(von).pop();
		hsd.get(nach).push(t);
		System.out.println(hsd);
		hanoi(hsd, index - 1, temp, nach, von);
	}

	public static void main(String[] args) {
		HashMap<String, ArrayDeque<String>> hsd = new HashMap<String, ArrayDeque<String>>();
		hsd.put("a", new ArrayDeque<String>(List.of("1", "2", "3")));
		hsd.put("b", new ArrayDeque<String>());
		hsd.put("c", new ArrayDeque<String>());
		hanoi(hsd, 3, "a", "b", "c");
	}

Code:
{a=[2, 3], b=[1], c=[]}
{a=[3], b=[1], c=[2]}
{a=[3], b=[], c=[1, 2]}
{a=[], b=[3], c=[1, 2]}
{a=[1], b=[3], c=[2]}
{a=[1], b=[2, 3], c=[]}
{a=[], b=[1, 2, 3], c=[]}

3 ist die größte Scheibe, was vorn steht (links) ist oben, was hinten steht (rechts) ist unten. Nun muss man von rechts nach links lesen....
 
X

Xyz1

Gast
Evtl noch dran denken dass HashMap die Reihenfolge ihrer Elemente zufällig wiedergeben kann.... Das heißt ggfs verwendest LinkedHashMap, aber das ist etwas overengineered.
 

Blender3D

Top Contributor
Ich verstehe nicht wie ich das weg kriege... Kann man bestimmte Consolen Ausgaben suppressen ?
Das liegt mit großer Wahrscheinlichkeit an deiner Bewegefunktion. Die Rekursion sollte so aussehen.
Java:
 public void bewege( int  numDiscs , HanoiTurm A, HanoiTurm B, HanoiTurm C) {
        if( numDiscs <=0)
            return;
        bewege(numDiscs-1, A, C, B);
        . .       
        bewege(numDiscs-1 ,C,A,B);
    }



Schau Dir einmal meine Lösung (Post #27) an, und versuche diese zu verstehen. Sie entspricht zwar nicht dem ungünstigen Klassenaufbau deines Professors aber sie funktioniert ohne Probleme und verdeutlicht das Konzept.
 

Kirby.exe

Top Contributor
Das liegt mit großer Wahrscheinlichkeit an deiner Bewegefunktion. Die Rekursion sollte so aussehen.
Java:
 public void bewege( int  numDiscs , HanoiTurm A, HanoiTurm B, HanoiTurm C) {
        if( numDiscs <=0)
            return;
        bewege(numDiscs-1, A, C, B);
        . .      
        bewege(numDiscs-1 ,C,A,B);
    }



Schau Dir einmal meine Lösung (Post #27) an, und versuche diese zu verstehen. Sie entspricht zwar nicht dem ungünstigen Klassenaufbau deines Professors aber sie funktioniert ohne Probleme und verdeutlicht das Konzept.
Hatte ich vorhin selbst gemerkt...habe auf den falschen gepusht xD Habe alles gefixt dankee :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K Algorithmus entwickeln Java Basics - Anfänger-Themen 1
laxla123 Eigenschaften eines Algorithmus (determiniert vs.. deterministisch) Java Basics - Anfänger-Themen 2
C Gewinnspiel erstellen mit Algorithmus Java Basics - Anfänger-Themen 3
C negamax-Algorithmus für Tic-Tac-Toe spielt manchmal falsch Java Basics - Anfänger-Themen 10
H Minimax Algorithmus in Tic Tac Toe Java Basics - Anfänger-Themen 3
M Minimax-Algorithmus für Vier gewinnt Java Basics - Anfänger-Themen 11
ohneInformatik; Trockentest Algorithmus, mathematischen Zusammenhang angeben Java Basics - Anfänger-Themen 3
M Minimax-Algorithmus Java Basics - Anfänger-Themen 17
mervanpolat Binary Search Algorithmus ausführen Java Basics - Anfänger-Themen 1
J Rekursiver Algorithmus Java Basics - Anfänger-Themen 9
M monte carlo Algorithmus für 4 gewinnt Java Basics - Anfänger-Themen 12
izoards Sortier Algorithmus für Bounding Box Elememte Links nach Rechts und von Oben nach Unten Java Basics - Anfänger-Themen 33
S Algorithmus entwicklen, der zu einem gegebenen Datum die Jahreszeit ermittelt Java Basics - Anfänger-Themen 13
rosima26 Merge-Algorithmus Java Basics - Anfänger-Themen 53
C Ein Algorithmus soll schneller werden Java Basics - Anfänger-Themen 24
D Dijkstra Algorithmus Hilfe!! Java Basics - Anfänger-Themen 9
U Den Kuchen aufteilen - aber wie? (Rebalancing-Algorithmus) Java Basics - Anfänger-Themen 14
s_1895 Pseudocode Naiver Algorithmus Java Basics - Anfänger-Themen 17
H String verschlüsseln - eigener Algorithmus Java Basics - Anfänger-Themen 104
T Algorithmus für Index mit min-Wert Java Basics - Anfänger-Themen 2
Düsseldorf2002 Testen meines Algorithmus Java Basics - Anfänger-Themen 1
D Primzahlen Rechner nach Eratostenes von Kyrene Algorithmus Java Basics - Anfänger-Themen 2
KogoroMori21 Frage zum Euklidischen Algorithmus Java Basics - Anfänger-Themen 11
S Algorithmus java searchAll IKey Java Basics - Anfänger-Themen 4
S Algorithmus Datensätze einfügen wenn... Java Basics - Anfänger-Themen 26
KogoroMori21 MergeSort Algorithmus Java Basics - Anfänger-Themen 2
KogoroMori21 Textdatei einlesen im Array (Selection Sort Algorithmus) Java Basics - Anfänger-Themen 3
fendix Compiler-Fehler Algorithmus zur Bestimmung von Primzahlen Java Basics - Anfänger-Themen 7
S Algorithmus (reelle Zahl <65536 von dezimal zu dual) max. 10 Nachkommastellen Java Basics - Anfänger-Themen 4
G Algorithmus Graphen Java Basics - Anfänger-Themen 10
D Input/Output fehlerhafter Algorithmus zum Ersetzen von Array-Werten nach logischem Schema Java Basics - Anfänger-Themen 1
N Selection Algorithmus: Methode wird nicht erkannt (BlueJ) Java Basics - Anfänger-Themen 3
U Meinung zum Dijkstra Algorithmus Java Basics - Anfänger-Themen 6
U Dijkstra Algorithmus Laufzeit Java Basics - Anfänger-Themen 3
L Math.exp also eigenen Algorithmus Java Basics - Anfänger-Themen 2
M Algorithmus Max-Heap? Java Basics - Anfänger-Themen 3
I Labyrinth auf der Basis eines rekursiven Algorithmus Java Basics - Anfänger-Themen 27
CptK Best Practice Algorithmus nach jedem Schritt zum Visualisieren pausieren Java Basics - Anfänger-Themen 3
A Algorithmus effizienter machen Java Basics - Anfänger-Themen 1
V Algorithmus zur fortlaufenden Berechnung des duechscjnt Java Basics - Anfänger-Themen 1
M Dijkstra Algorithmus in Graphen auf mehrere verschiedene Knoten anwenden lassen Java Basics - Anfänger-Themen 11
O Labyrinth Algorithmus Java Basics - Anfänger-Themen 3
G Quicksort Algorithmus Java Basics - Anfänger-Themen 12
S Binäre-Suche Algorithmus Java Basics - Anfänger-Themen 1
D Algorithmus in Pseudocode mit log2(n) Operationen erstellen Java Basics - Anfänger-Themen 3
C Laufzeit eines Sortier-Algorithmus ermitteln Java Basics - Anfänger-Themen 4
H aufgabe java luhn algorithmus Java Basics - Anfänger-Themen 10
A Datenstruktur für Savings Algorithmus und Planung von kleinen Programmierprojekten Java Basics - Anfänger-Themen 1
J Algorithmus für eine Reihe implementieren Java Basics - Anfänger-Themen 2
S Dijkstra Algorithmus funktioniert nicht Java Basics - Anfänger-Themen 4
N Denksportaufgabe durch Algorithmus lösen Java Basics - Anfänger-Themen 2
S Problem mit einem rekursivem FloodFill Algorithmus Java Basics - Anfänger-Themen 62
B Algorithmus Square und Multiply Java Basics - Anfänger-Themen 3
J Algorithmus - Strings auf eigene Reihenfolge miteinander vergleichen Java Basics - Anfänger-Themen 4
D Frage Boyer-Moore Algorithmus Java Basics - Anfänger-Themen 7
M Komplexität Algorithmus Java Basics - Anfänger-Themen 8
H Zeichen im algorithmus Java Basics - Anfänger-Themen 4
B Code Verständnisfragen - FLoyd Warshall Algorithmus Java Basics - Anfänger-Themen 1
B Algorithmus zum entmischen einer Zahlenfolge Java Basics - Anfänger-Themen 15
X Minimax-Algorithmus über alle Kanten möglich? - Kanten darstellen Java Basics - Anfänger-Themen 1
T Algorithmus zur Überprüfung eines binären Suchbaums Java Basics - Anfänger-Themen 2
K Best Practice Algorithmus für Berechnung von Zahlenreihenfolge Java Basics - Anfänger-Themen 12
M Simpler Algorithmus läuft extrem langsam. Java Basics - Anfänger-Themen 3
K Erste Schritte Brute Force Algorithmus Java Basics - Anfänger-Themen 2
L Frage zu BubbleSort Algorithmus Java Basics - Anfänger-Themen 2
B gibt es ein Stundenplan-Algorithmus? Java Basics - Anfänger-Themen 11
O Algorithmus-Problem Java Basics - Anfänger-Themen 5
P Euklidischer Algorithmus Java Basics - Anfänger-Themen 9
L Greates Commong Dividend - euklidischer Algorithmus, modulos not positive Java Basics - Anfänger-Themen 5
J Euklidischer Algorithmus Java Basics - Anfänger-Themen 1
S Quicksort Algorithmus Java Basics - Anfänger-Themen 2
S GraphNode --- Dijkstra Algorithmus : NullPointerException Java Basics - Anfänger-Themen 1
B Rekursive Algorithmus schreiben Java Basics - Anfänger-Themen 8
V Algorithmus in einer Methode ausführen Java Basics - Anfänger-Themen 3
M Implementierung des Knuth-Morris-Pratt-Algorithmus Java Basics - Anfänger-Themen 0
M Dijkstras Algorithmus Java Basics - Anfänger-Themen 5
S Zusammenhang Datenstruktur/Algorithmus Java Basics - Anfänger-Themen 1
M Simulation - Algorithmus Java Basics - Anfänger-Themen 3
F Erste Schritte Hilfe beim Algorithmus finden Java Basics - Anfänger-Themen 8
D Algorithmus für Punkte auf einem Kreis Java Basics - Anfänger-Themen 0
D Algorithmus zu gegebener Laufzeit implementieren Java Basics - Anfänger-Themen 1
B Doppelte Werte aus Array entfernen ohne Import - Algorithmus Java Basics - Anfänger-Themen 5
C Ideen für einen Algorithmus Java Basics - Anfänger-Themen 1
F Best Practice Algorithmus optimieren - Binaeruhr Java Basics - Anfänger-Themen 2
S Euklid Algorithmus zur Berechnung des GGTs Java Basics - Anfänger-Themen 2
L Welcher Algorithmus ist das ? Java Basics - Anfänger-Themen 9
J Rekursiver Horner-Schema-Algorithmus - Verstehe ich ihn richtig? Java Basics - Anfänger-Themen 2
O Java Zufalls-Verteil-Algorithmus Java Basics - Anfänger-Themen 3
P ganz simpler algorithmus Java Basics - Anfänger-Themen 3
C Sortieren ohne Algorithmus Java Basics - Anfänger-Themen 8
J Algorithmus: Grad von floating zu Grad/Minute/Sekunde Java Basics - Anfänger-Themen 3
A Text Verschriebung/Algorithmus(?) Java Basics - Anfänger-Themen 8
R Rekursionsformel für Laufzeit von Algorithmus Java Basics - Anfänger-Themen 3
E Algorithmus für kart. Produkt: als int [] Feld repräsentiert Java Basics - Anfänger-Themen 10
U Peterson Algorithmus Java Basics - Anfänger-Themen 13
algebraiker Collections Bräuchte Hilfe bei dem Algorithmus - LinkedHashMap Java Basics - Anfänger-Themen 2
S A* Path Algorithmus in Java schon vorhanden Java Basics - Anfänger-Themen 3
S Bubble Sort Algorithmus Java Basics - Anfänger-Themen 3
N Unerklärlich: Rekursiver Algorithmus gibt falschen Datentyp zurück... Java Basics - Anfänger-Themen 4
S Algorithmus (Programmablaufplan) Java Basics - Anfänger-Themen 11

Ähnliche Java Themen

Neue Themen


Oben