Brauche mal Hilfe bei Backtracking Algo (Sudoku)



  • Hallo. Ich bräuchte hier mal Hilfe bei meiner versuchten Sudoku Lösung.

    #include <iostream>
    using namespace std;
    
    typedef int sfeld[9][9];
    void Ausgabe(sfeld);
    bool Loese(sfeld, int, int);
    bool Pruefe(sfeld, int, int, int);
    
    int main()
    {
    	sfeld Sudoku = {0,7,2,0,3,9,1,0,0,0,0,0,1,5,0,6,0,0,5,0,0,4,2,0,0,0,7,0,6,0,0,0,0,0,9,0,4,0,0,9,7,3,0,0,0,0,9,3,0,6,0,0,4,0,8,0,0,3,1,0,9,6,0,0,0,6,0,0,8,0,0,0,9,0,0,0,0,0,2,7,0};
    
    	Ausgabe(Sudoku);
    
    	if (!Loese(Sudoku, 0, 0))
    	{
    		cout << "Keine Lösung!" << endl;
    	}
    	cin.get();
    }
    
    bool Pruefe(sfeld TehFeld, int Zeile, int Spalte, int Wert)
    {
    	for (int i=0; i<9; i++)
    	{
    		if ((Zeile != i) && (Wert == TehFeld[i][Spalte])) { return 0; } //prüfen, ob der Wert in der Spalte schon enthalten ist
    	}
    
    	for (int i=0; i<9; i++)
    	{
    		if ((Spalte != i) && (Wert == TehFeld[Zeile][i])) { return 0; } //prüfen, ob der Wert in der Zeile schon enthalten ist
    	}
    
    	int k, l;
    	k = (Zeile / 3);
    	l = (Spalte / 3);
    
    	for (int i = k*3; i < k*3+3; i++)
    	{
    		for (int j = l*3; j < l*3+3; j++)
    		{
    			if (((Zeile != i) || (Spalte != j)) && (Wert == TehFeld[i][j])) { return 0; } //prüfen, ob Wert in Subquadrat schon enthalten ist
    		}
    	}
    	return 1;
    }
    
    bool Loese(sfeld TehFeld, int Zeile, int Spalte)
    {
    	if (Zeile*Spalte > 64) { Ausgabe(Sudoku); return 1; } //Lösung gefunden
    	int n,m;
    	n = Zeile;
    	m = Spalte;
    	n++;
    	if (n >= 8) { n = 0; m++; }
    
    	if (TehFeld[Zeile][Spalte] == 0) //nur Felder bearbeiten, in denen noch keine Zahl vorgegeben ist
    	{
    		for (int i=1; i<=9; i++)
    		{
    			if (Pruefe(TehFeld, Zeile, Spalte, i))
    			{
    				TehFeld[Zeile][Spalte] = i;
    				if (Loese(TehFeld, n, m)) { return 1; }
    			}
    		}
    	}
    	else //wenn schon Zahl vorgegeben, direkt zum nächsten Feld
    	{
    		if (Loese(TehFeld, n, m)) { return 1; }
    	}
    	return 0;
    }
    
    void Ausgabe(sfeld Feld)
    {
    	for(int i=0; i < 9; i++)
    	{
    		for(int j=0; j < 9; j++)
    		{
    			cout << Feld[i][j] << " ";
    		}
    		cout << endl;
    	}
    }
    

    Ich weiß, es gibt fertige Lösungen zuhauf im Web, aber ich sitze nun schon seit Stunden hier vor meinem Code und kapier einfach nicht, warum es noch nicht funktioniert.
    Er beginnt zwar, Lösungen für die Felder zu suchen, irgendwo bricht er dann aber immer verfrüht ab und ich weiß nicht, wieso.
    Erkennt jemand den Fehler und kann mir weiterhelfen? 😕



  • sfeld ist ein array und wird folglich nicht per value als Kopie übergeben. Das bedeutet aber, dass du getestete Felder manuell zurücksetzen musst, also

    TehFeld[Zeile][Spalte] = i;
                    if (Loese(TehFeld, n, m)) { return 1; }
                    TehFeld[Zeile][Spalte] = 0;
    

    würde ich jedenfalls nach einmal Überfliegen sagen...



  • camper schrieb:

    sfeld ist ein array und wird folglich nicht per value als Kopie übergeben.

    Oh, das war mir nicht direkt bewusst. Hatte mich zwar an anderer Stelle schon gewundert, dass ich Arrays nicht explizit als Referenz übergeben konnte, aber nunja 😉 Ist mein erster Tag mit C/C++ heute quasi.
    Jedenfalls scheint es so tatsächlich zu funktionieren (wenn ich noch den Ausdruck in Zeile 55 in "n > 8" statt "n >= 8" ändere, my bad).

    Vielen Dank!


Anmelden zum Antworten