Probleme mit verschachtelten for-Schleifen

JavaMeetsBlueJ

Bekanntes Mitglied
Hallo Forum-User,

der nachfolgende Quelltext ist deshalb so lang, um Verständisprobleme von vornherein auszuräumen. Im wesentlichen wundert mich die Ausgabe die aus den drei for-Schleifen am Ende des Quelltextes resultiert.

Java:
public class Sudoku2
{
public static void main (String[] args)
{
 
 // Initialisierung der Zahlen: Felder -> Zeilen; Element -> Spalten
  int koordinate[][] = 
 {
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9}, 
    {1,2,3,4,5,6,7,8,9} };
 // Initialisierung der Laufvariablen
  int z = 0;
  int e = 0;
// Methodenaufruf (Bringt de Zahlen in zugehörige Reihen und Spalten)
  setzahlen(koordinate, z, e);

}

public static void setzahlen(int koordinate[][], int z, int e)
{

// Zeilen werden um 1 erhöht
 for( ; z <= 8; z++ )
 {
  // Spalten werden um 1 erhöht
     for( ; e <= 8; e++)
    {
    
    System.out.print(koordinate[z][e] + " ");
    }
    System.out.println();
   // Initialisierung von s, damit wieder bei Spalte 1(0) angefangen wird
    e = 0;
 }
 z = 0; // Zeile
 e = 0; // Element
 int p = 1; //Element in der selben Zeile wie e. Hiermit wird ein doppeltes Vorkommen von e geprüft
 
 for( ; z <= 8; z++)
    {
     for( ; e <= 8; e++ )
       {
    
       for( ; p <= 8; p++)
            {
             if (koordinate[z][e] == koordinate[z][p])
                 {
                  System.out.println("Das Sudoku wurde nicht gelöst");
                 }
                   else 
                      {
                         System.out.println("Zeile " + z + " ist Fehlerfrei");
                      }
             }

           }
     }
    
       
}
    }

Und zwar folgendes: Auf der Kosole wird ausgegeben:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei
Zeile 0 ist Fehlerfrei

Wieso wird
1) z nicht erhöht, bleibt also 0 und

2) wieso wird nicht angezeigt "Das Sudoku wurde nicht gelöst", denn wenn ich das zweite Element aus der ersten Zeile habe und prüfe auf doppeltes Vorkommen, wird ja bei koordinate [z][0] angefangen und p inkrementiert. wenn jetzt e und p gleich sind, befindet man sich auf dem exakt identischen Feld, was die Fehlermeldungzufolge haben müsste, diese wird aber nicht ausgegeben("Sudoku wrde nicht gelöst")

lg

PS: Ich weiß, dass ich nicht der ertse bin, der Sudokus auf Korrektheit überprüfen möchte, hier geht es mir aber in ertser Linie darum, den Fehler zu kennen, weniger um den perfekten Lösungsalgorithmus eines Sudokus, denn ich weiß, dass ich weder 3x3 Kästchen noch Spalten auf die Richtigkeit hin prüfe.
 
Zuletzt bearbeitet:
Java:
System.out.println("Bei "+z+" "+e+" ist "+koordinate[z][e]+" und bei "+z+" "+p+" ist "+koordinate[z][p]);
if (koordinate[z][e] == koordinate[z][p])
{
    ...
}
Du wirst auch lernen müssen, solche Sachen selbst zurückzuverfolgen. So eine Ausgabe kann dabei helfen.
 
Das sind definitiv nicht alle Ausgaben.

Du hast da noch 2 weitere for-loops drinne. Die laufen von 9 und einmal 8 mal. Und das für jedes z.
Also vermutlich wirst du für jedes z 72 Ausgaben bekommen.
 
Zuletzt bearbeitet:
Was mich wundert: warum p = 1 ?
Du willst anscheinend, dass e == p nicht auftritt. Das wird es so aber, denn spätestens beim zweiten durchlauf ist e = 1 und das feld p startet auch bei 1. Somit vergleichst du dann ob die Werte im selben Feld gleich sind. Außerdem prüfst du nie, ob das Element [0] == e ist, da p bei dir immer bei 1 startet.
 
Abgesehen davon, dass p =1 von mir natürlich blanker Unsinn ist, wundert mich gerade dass, was du ebenso festgestellt hast, nämlich, dass ich das selbe Feld mit sich selbst vergleiche, was laut Code eigentlich die Ausgabe "Sudoku wurde nicht gelöst(bezieht sich auf den Anwender)" zur Folge haben müsste, dies passiert jedoch nicht und das wundert mich.
-> Ich weiß ja, dass ich z.BFeld [0][3] mit Feld [0][3] vergleiche, dass aber nicht der gewünschte Fehlertext ausgegeben wird wundert mich arg. Vielleicht ein dummer Anfängerfehler... bisher hab ich's noch nicht.

lg
 
Java:
	public static void main(String[] args)
	{
		
		// Initialisierung der Zahlen: Felder -> Zeilen; Element -> Spalten
		int koordinate[][] = { { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 },
				{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } };
		// Initialisierung der Laufvariablen
		int z = 0;
		int e = 0;
		// Methodenaufruf (Bringt de Zahlen in zugehörige Reihen und Spalten)
		setzahlen(koordinate, z, e);

	}

	public static void setzahlen(int koordinate[][], int z, int e)
	{
		// Zeilen werden um 1 erhöht
		for (; z <= 8; z++)
		{
			// Spalten werden um 1 erhöht
			for (; e <= 8; e++)
			{
				System.out.print(koordinate[z][e] + " ");
			}
			System.out.println();
			// Initialisierung von s, damit wieder bei Spalte 1(0) angefangen
			// wird
			e = 0;
		}

		for (z = 0; z <= 8; z++)
		{
			for (e = 0; e <= 8; e++)
			{
				for (int p =0; p <= 8; p++)
				{
					if (koordinate[z][e] == koordinate[z][p])
					{
						System.out.println("Das Sudoku wurde nicht gelöst");
					}
					else
					{
						System.out.println("Zeile " + z + " ist Fehlerfrei");
					}
				}
			}
		}
	}

So sollte es gehen 🙂

natürlich ist der Vergleich mit sich selbst immer noch da, den musst DU aber beheben
 
Zuletzt bearbeitet:
Übersehe ich etwas oder ist der einzige Unterschied der, dass bei deinem Beispiel die Variablen lediglich innerhalb von for() initialiesiert werden?

lg
 
Zuletzt bearbeitet:
Sind denn 4 Verschachtelungsebenen unbedingt nötig? Auf Anhieb sehe ich nicht mal, was der Code machen soll. Wenn er irgendwie zeilen- und spaltenweise das Spielfeld durchgeht, dann schreib Dir Methoden mit geeignetem Parameter, return value und sprechendem Namen und pack je eine for-Schleife in eine Methode. Dann durchschaust Du es leichter. Und vor allem sagt dann der Methodenname, welche Idee hinter Deinem Code steckt. Kommentare sind da nur eine Krücke, die i.d.R mit zunehmendem Entwicklungsstand auch noch die Tendenz haben, garnicht mehr das zu beschreiben, was der Code macht.
 
Der Tip, die Variablen in dem for() zu initialisieren bringt mich ein gutes Stück weiter in die richtige Richtung, aber wieso eigentlich?

Ausgabe ist folgende:

Bei 8 4 ist 5 und bei 8 3 ist 4
Bei 8 4 ist 5 und bei 8 4 ist 5
Das Sudoku wurde nicht gelöst
Bei 8 4 ist 5 und bei 8 5 ist 6
Bei 8 4 ist 5 und bei 8 6 ist 7
Bei 8 4 ist 5 und bei 8 7 ist 8
Bei 8 4 ist 5 und bei 8 8 ist 9
Bei 8 5 ist 6 und bei 8 0 ist 1
Bei 8 5 ist 6 und bei 8 1 ist 2
Bei 8 5 ist 6 und bei 8 2 ist 3
Bei 8 5 ist 6 und bei 8 3 ist 4
Bei 8 5 ist 6 und bei 8 4 ist 5
Bei 8 5 ist 6 und bei 8 5 ist 6
Das Sudoku wurde nicht gelöst
Bei 8 5 ist 6 und bei 8 6 ist 7
Bei 8 5 ist 6 und bei 8 7 ist 8
Bei 8 5 ist 6 und bei 8 8 ist 9
Bei 8 6 ist 7 und bei 8 0 ist 1
Bei 8 6 ist 7 und bei 8 1 ist 2
Bei 8 6 ist 7 und bei 8 2 ist 3
Bei 8 6 ist 7 und bei 8 3 ist 4
Bei 8 6 ist 7 und bei 8 4 ist 5
Bei 8 6 ist 7 und bei 8 5 ist 6
Bei 8 6 ist 7 und bei 8 6 ist 7
Das Sudoku wurde nicht gelöst
Bei 8 6 ist 7 und bei 8 7 ist 8
Bei 8 6 ist 7 und bei 8 8 ist 9
Bei 8 7 ist 8 und bei 8 0 ist 1
Bei 8 7 ist 8 und bei 8 1 ist 2
Bei 8 7 ist 8 und bei 8 2 ist 3
Bei 8 7 ist 8 und bei 8 3 ist 4
Bei 8 7 ist 8 und bei 8 4 ist 5
Bei 8 7 ist 8 und bei 8 5 ist 6
Bei 8 7 ist 8 und bei 8 6 ist 7
Bei 8 7 ist 8 und bei 8 7 ist 8
Das Sudoku wurde nicht gelöst
Bei 8 7 ist 8 und bei 8 8 ist 9
Bei 8 8 ist 9 und bei 8 0 ist 1
Bei 8 8 ist 9 und bei 8 1 ist 2
Bei 8 8 ist 9 und bei 8 2 ist 3
Bei 8 8 ist 9 und bei 8 3 ist 4
Bei 8 8 ist 9 und bei 8 4 ist 5
Bei 8 8 ist 9 und bei 8 5 ist 6
Bei 8 8 ist 9 und bei 8 6 ist 7
Bei 8 8 ist 9 und bei 8 7 ist 8
Bei 8 8 ist 9 und bei 8 8 ist 9
Das Sudoku wurde nicht gelöst


Dass da die Hälfte fehlt, liegt an der hammermäßigen BlueJ-Konsole, die ganze 46 Zeilen anzeigt.😉

Den Hinweis auf mehrere Methoden finde ich allerdings auch nicht schlecht.

lg
 
Zuletzt bearbeitet:
Also, um auf den Vorschlag mit mehreren Methoden zurückzukommen: War es so gemeint, dass jede Methode ihre eigene for-Schleife hat und diese Methoden in einer anderen Methode aufgerufen werden?
Das würde ja bedeuten, dass ich an eine Methode als Parameter eine Methode übergeben müsste. Geht das überhaupt und wenn ja wie funktioniert das?


lg
 
Also, mit folgendem Code bekomme ich das was ich möchte, ist zwar nur ein Test, wegen System.out, aber jede Zahl in jeder Zeile wird innerhalb der Zeile neunmal auf doppeltes Vorkommen hin untersucht. Wenn die Stelle der Spalte der Stelle des geprüften Elements ist, wird dies ignoriert.


Java:
public class Kontrollstrukturen
{
public static void main (String[] args)
 {
int koordinate[][] = {
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9},
    {1,2,3,4,5,6,7,8,9}, 
    {1,2,3,4,5,6,7,8,9} };
    
    
    int zeile = 0;
    int spalte = 0;
    int element = 0;
    
   // leseEingaben(zeile,spalte, element,koordinate);
    pruefe_doppeltesVorkommen(zeile,spalte, element,koordinate);
    
 }

 public static void leseEingaben(int zeile, int spalte, int element, int koordinate[][])

 {
  for(zeile = 0; zeile <= 8; zeile++)
  {
    for (spalte = 0; spalte <= 8; spalte++)
    {
    System.out.print(koordinate[zeile][spalte] + " ");
    }
     System.out.println("");
     spalte = 0;
   }
}



 public static void pruefe_doppeltesVorkommen(int zeile, int spalte, int element, int koordinate[][])
  {
    zeile = 0;
    element = 0;
    
    for(zeile = 0; zeile <= 8; zeile++)
    {
      for (element = 0; element <= 8; element++)
        {
          for(spalte = 0; spalte <= 8; spalte++)
          {
              if(koordinate[zeile][element] == koordinate[zeile][spalte] && spalte != element)
              {
               System.out.println("Zahl in Zeile " + (zeile + 1) + " und Spalte " + (spalte + 1) + " IST GLEICH DER ZAHL IN SPALTE " + (element + 1));   
              }
              
              if(koordinate[zeile][element] != koordinate[zeile][spalte])
              {
                  System.out.println("Zahl in Zeile " + (zeile + 1) + " und Spalte " + (spalte + 1) + " ist ungleich der Zahl in Spalte " + (element + 1));
              }
          }
        }
    }
  }
 
}


Danke für die Tipps
 
Zuletzt bearbeitet:
Überflogen... Gewöhn' dich dran, dass bei 0 angefangen wird, und solche Zeilen
for(zeile = 0; zeile <= 8; zeile++)
eben
for(zeile = 0; zeile < 9; zeile++)
lauten sollten... (Nur nebenbei....)
 
Ich vermisse das Rücksetzen der Variablen p und e innerhalb deiner for-Schleifen. Kein Wunder, dass die Inneren deswegen nur einmal durchlaufen werden und z deswegen scheinbar nicht hochzählt. Faktisch tut es das nämlich, es wird nur nicht mehr angezeigt. Also Marcos Tip und...
Java:
boolean solved = true;
for(int z = 0; z < 9 && solved; z++) {
  for(int e = 0; e < 8 && solved; e++) {
    for(int p = e + 1; p < 9 && solved; p++) {
      solved &= koordinate[z][e] != koordinate[z][p];
    }
  }
}
System.out.println((solved)? "Das Sudoku ist fehlerfrei" : "Das Sudoku wurde nicht gelöst");
 
Zuletzt bearbeitet von einem Moderator:
Der Code mit dem boolean-Block gefällt mir, dann kann ich am ende einfach fragen ob pruefe_eilen,pruefe_spalten und pruefe_3x3_kaestchen (das sind die drei Methoden) den wert true zurückliefern und dann über if alles prüfen und wenn jede methode den wert true zurückliefert, wird angezeigt, dass das Sudoku gelöst wurde.

Edit:
So hab ich mir das jetzt gebastelt, jedoch liefert das einen Compilerfehler "unreachable statement"

Java:
  if(koordinate[zeile][element] == koordinate[zeile][spalte] && spalte != element)
                    {
                        break;
                        isZeile = false;
                    }

lg
 
Zuletzt bearbeitet:
Nach dem break wird die nächste Zeile nicht mehr ausgefhrt. Mehr code posten. Abgesehen davon: Wenn man das (was empfehlenswert ist) in eine Methode packt, kann man
Java:
boolean check()
{
    for (....)
    {
        if (somethingWrong) return false;
    }
    return true;
}
machen.
 
Der komplette Code vom Programm ist folgender. Jetzt funktionieren alle Methoden, das Problem ist nur, dass ich die Getter vergessen hab und deshalb die letzte Methode nicht auf die aktualisierten booleans-Variablen zugreifen kann.


Java:
/**
 * Lösungsmechanismen, um ein Sudoku zu prüfen.
 * 
 * @author Tobias Rüffer 
 * @version 1.0; 04.03.2012
 */

public class Kontrollstrukturen
{
    public static void main (String[] args)
    {
        int koordinate[][] = {
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9}, 
                {1,2,3,4,5,6,7,8,9} };

        int kaestchen[][] = new int[9][9];
        int spalte = 0;
        int zeile = 0;
        int element = 0;
        int count = 0;
        int count2 = 0;
        int i = 0;
        int spaltenanfang = 0;
        int spaltenende = 2;
        int zeilenanfang = 0;
        int zeilenende = 2;
        boolean isZeile = true ; // 1 gilt als Definition von wahr
        boolean isSpalte = true ;
        boolean isKaestchen = true ;

      
         //leseEingaben(zeile,spalte, element,koordinate);
         //pruefe_doppeltesVorkommen_in_Zeile(zeile,spalte, element,koordinate,isZeile);
        // pruefe_doppeltesVorkommen_in_Spalte( zeile, spalte, element, koordinate, isSpalte);
        pruefe_doppeltesVorkommen_in_dreimaldrei_Kaestchen(zeile, spalte, koordinate, kaestchen, count, count2, i, spaltenende,spaltenanfang,zeilenende, zeilenanfang, element, isKaestchen);
        pruefe_Ergebnisse(isZeile, isSpalte,isKaestchen);
    }

    public static void leseEingaben(int zeile, int spalte, int element, int koordinate[][])

    {
        for(zeile = 0; zeile <= 8; zeile++)
        {
            for (spalte = 0; spalte <= 8; spalte++)
            {
                System.out.print(koordinate[zeile][spalte] + " ");
            }
            System.out.println("");
            spalte = 0;
        }
    }
    // hier könnte noch eine Bedingeung rein, damit nur Zahlen von 1 bis 9 eine richtige Eingabe sind

    public static void pruefe_doppeltesVorkommen_in_Zeile(int zeile, int spalte, int element, int koordinate[][], boolean isZeile)
    {
        zeile = 0;
        element = 0;

        for(zeile = 0; zeile <= 8; zeile++)
        {
            for (element = 0; element <= 8; element++)
            {
                for(spalte = 0; spalte <= 8; spalte++)
                {
                    if(koordinate[zeile][element] == koordinate[zeile][spalte] && spalte != element)
                    {

                        isZeile = false;
                        break;
                    }

                    if(koordinate[zeile][element] != koordinate[zeile][spalte])
                    {
                        System.out.println("Zahl in Zeile " + (zeile + 1) + " und Spalte " + (spalte + 1) + " ist ungleich der Zahl in Spalte " + (element + 1));
                    }
                }
            }
        }
    }

    public static void pruefe_doppeltesVorkommen_in_Spalte(int zeile, int spalte, int element, int koordinate[][], boolean isSpalte)
    {
        zeile = 0;
        spalte = 0;
        element = 0;

        for(spalte = 0; spalte <= 8; spalte++)
        {
            for(element = 0; element <= 8; element++) 
            {
                for(zeile = 0; zeile <= 8; zeile++)
                {
                    if(koordinate[zeile][spalte] == koordinate[element][spalte] &&  zeile != element   )
                    {
                        isSpalte = false;
                        break;

                    }

                    if(koordinate[zeile][spalte] != koordinate[element][spalte])
                    {
                        System.out.println("Die Zahl in Spalte " + (spalte+1) + "und Zeile" + (zeile+1) + "ist UNGLEICH der Zahl in Zeile" + (element+1)); 
                    }
                }
            }
        }
    }

    public static void pruefe_doppeltesVorkommen_in_dreimaldrei_Kaestchen(int zeile, int spalte, int koordinate[][], int kaestchen[][], int count, int count2, int i, int spaltenanfang,int spaltenende, int zeilenanfang, int zeilenende, int element,boolean isKaestchen)
    {
        zeile = 0;
        spalte = 0;

        count = 0;
        count2 = 0;
        i = 0;
        spaltenanfang = 0;
        spaltenende = 2;
        zeilenanfang = 0;
        zeilenende = 2;

        // Hier muss so schnell wie möglich ein vernünftiger Algorithmus hinne!!!
        for(count = 0; count <= 8; count++)

        {
            for(zeile = 0; zeile <= 2; zeile++)
            { 

                for(spalte = spaltenanfang; spalte <= spaltenende; spalte++) 
                {

                    kaestchen[count2][i] = koordinate[zeile][spalte];

                    System.out.print(kaestchen[count][i]);
                    i++;

                }

            } 
            count2++;
            i = 0;
            if(spaltenende <= 8)
            {spaltenanfang += 3;
                spaltenende += 3;
                if(spaltenende > 8)
                {
                    zeilenanfang += 3;
                    spaltenanfang = 0;
                    spaltenende = 2;
                }
            }

        }

        for(count = 0; count <= 8; count++)
        {
            for(element = 0; element <= 8; element++) 
            {
                for(count2 = 0; count2 <= 8; count2++)
                {
                    if(kaestchen[count][element] == kaestchen[count][count2] && element != count2)
                    {

                        isKaestchen = false;
                        break;

                    }

                    
                }
             
            }  
        }
    }

    public static void pruefe_Ergebnisse(boolean isZeile, boolean isSpalte, boolean isKaestchen)
    {
        if(isZeile == false || isSpalte == false|| isKaestchen == false)
        {
            System.out.println("Das Sudoku enthält einen Fehler");
        }
        else
        {
            System.out.println("Das Sudoku wurde erfolgreich gelöst");
        }
    }

    
}

lg
 

Neue Themen


Zurück
Oben