Prüft, ob ein Wert in einem Array existiert - C++



  • Hallo, Ich habe ein Array[9][9]=
    {{1,2,3,4,5,6,7,8,9},
    {4,5,6,7,8,9,1,2,3},
    {7,8,9,1,2,3,4,5,6},
    {2,3,4,5,6,7,8,9,1},
    {5,6,7,8,9,1,2,3,4},
    {8,9,1,2,3,4,5,6,7},
    {3,4,5,6,7,8,9,1,2},
    {6,7,8,9,1,2,3,4,5},
    {9,1,2,3,4,5,6,7,8}};

    und jetzt soll ich die unteren Regeln überprüfen.
    Und zwar wollte ich eine boolische funktion dafür entwerfen die wenn die Regel wahr is true ausgibt und wenn sie Falsch is false.
    ich weis echt nicht weiter.

    Bin für jede Form von Hilfe dankbar, aber nicht einfach einen fertigen code postn, ich muss das verstehen

    1. Alle Zahlen von 1 bis 9 muessen in jeder Zeile vorkommen.
    2. Alle Zahlen von 1 bis 9 muessen in jeder Spalte vorkommen.
    3. Zerlegt man die Matrix in 3 × 3 Unterbloecke, so muessen alle Zahlen von 1 bis 9 in
    jedem dieser Unterblöecke vorkommen.


  • Mod

    Und deine Frage ist?

    Du gehst jeweils alle diese Strukturen durch und markierst dir irgendwo, welche Ziffern vor gekommen sind. Sind nach Durchlaufen der Struktur alle Ziffern markiert, dann ist die Regel (für diesen Abschnitt) erfüllt.

    Dieses Merken, welche Ziffern vorkamen, kann beispielsweise erfolgen, indem du dir ein Array mit 9 bools machst. Oder für die coolen Kinder, die schon ins tiefe Wasser dürfen, kann man auch einen einzigen großen Zahlenwert nehmen und ein bisschen Bits hin und her schieben.



  • Erstmal danke für die schnelle antwort

    Meine frage ist wie markier ich denn diese ziffern ??
    und wie sieht denn so eine boolische funktion mit einem array aus ?

    sorry aber weiß grad nicht weiter

    ein allgemeines beispiel wäre ganz nett 🙂


  • Mod

    Für jeden Block/Reihe/Spalte:
    {
      bool digits[9] = {0};
      Iteriere über Block:
      {
        digits[ziffer_an_dieser_stell_im_block - 1] = true;
      }
      Iteriere über alle digits:
      {
        if (wert_an_dieser_stelle_in_digits == false):
        {
          Rückgabe: Fehler
        }
      }
    }
    Rückgabe: Alles in Ordnung
    

    Wobei das zwar das ist, wonach du gefragt hast, aber wahrscheinlich nicht das, was du suchst. Du willst doch vermutlich eher wissen, ob ein unvollständig ausgefülltes Sudoku eine Lösung sein kann? Falls ja, müsstest du das Vorkommen der einzelnen Ziffern zählen, da dann ja auch Ziffern mehrmals vorkommen könnten (was dann ein Fehler wäre). Bei obigem Beispiel ist dieser Fall ausgeschlossen, denn wenn eine Ziffer mehrmals vorkommt, dann kommt ja automatisch eine andere Ziffer nicht vor, da in jedem Block genau 9 Ziffern sind. Falls der Wert 0 ein unausgefülltes Kästchen darstellt, dann kann man leicht den obigen Code für diesen Fall abwandeln:

    Für jeden Block/Reihe/Spalte:
    {
      int digit_count[10] = {0};
      Iteriere über Block:
      {
        ++digit_count[ziffer_an_dieser_stell_im_block];
      }
      Iteriere über digit_count von 1 bis 9:  // Die 0 wird nicht geprüft, da sie mehrfach vorkommen darf
      {
        if (wert_an_dieser_stelle_in_digit_count != 1):
        {
          Rückgabe: Fehler
        }
      }
    }
    Rückgabe: Alles in Ordnung
    


  • Mir ist schon etwas klarer geworden was du meinst und mit dem Sodoku hast du recht, aber das Problem ist ein anderes. Ich soll aus dem obigen array einfach nur überprüfen ob 3 Regeln erfüllt sind mit eine boolischen Funktionen die so aussehen sollten:

    bool SudokuRowIsValid(Sudoku s, int rowIndex);

    bool SudokuColumnIsValid(Sudoku s, int colIndex);

    bool SudokuBlockIsValid(Sudoku s, int blockIndX, int blockIndY)

    Ich kam jetzt schon so weit dass ich diesen Code zusammen bekommen habe:

    #include <iostream>
    using namespace std;
    
    typedef int Sudoku[9][9];
    int x = 9;
    int y = 9;
    int i;
    int j;
    
    Sudoku s = {{1, 2, 3, 4, 5, 6, 7, 8, 9},
    {4, 5, 6, 7, 8, 9, 1, 2, 3},
    {7, 8, 9, 1, 2, 3, 4, 5, 6},
    {2, 3, 4, 5, 6, 7, 8, 9, 1},
    {5, 6, 7, 8, 9, 1, 2, 3, 4},
    {3, 4, 5, 6, 7, 8, 9, 1, 2},
    {8, 9, 1, 2, 3, 4, 5, 6, 7},
    {6, 7, 8, 9, 1, 2, 3, 4, 5},
    {9, 1, 2, 3, 4, 5, 6, 7, 8}};
    
    void sodoku_grid ()
    {
          for (i=0; i<x; i++)
         {
              for (j=0;j<y;j++)
              {
                  cout<<"\t"<<s[i][j];
              }
              cout <<"\n\n";
         }
    }
    
    bool checkRow( int i)
       {
          for( int j = 0; j < 9; j++ )
             if( s[i][j] == 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9  ) return true;
                else if ( s[i][j] != 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9  ) return false ;
    
       }
    
    bool checkCol( int j)
       {
          for( int i = 0; i < 9; i++ )
             if( s[i][j] == 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9  ) return true;
                else if( s[i][j] != 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9  ) return false;
    
       }
    
       bool checkBox( int i, int j)
       {
          i = (i / 3) * 3 ;
          j = (j / 3) * 3 ;
    
          for( int r = 0; r < 3; r++ )
             for( int c = 0; c < 3; c++ )
             if( s[i+r][j+c] ==  1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 ) return true;
                else if  ( s[i+r][j+c] !=  1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 ) return false;
    
       }
    
    int main ( )
    {
    
    cout << checkRow(9) << endl;
    cout << checkCol(9) << endl;
    cout << checkBox(9,9) << endl;
    
        sodoku_grid();
    
    }
    

    aber irgendwie überprüft er nicht die Werte
    ich werd noch wahnsinnig haha 😕 😕 😕


  • Mod

    if(s[i][j] == 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9 )

    Da steht auf Deutsch übersetzt: "Falls s[i][j] gleich 1"

    Der Ausdruck rechts vom == wird zuerst ausgewertet und 1 || 2 || ... ist nichts anderes als true bzw. 1.

    Wenn du wissen möchtest, ob s[i][j] einen Wert aus 1, 2, ... , 9 hat, dann musst du einzeln vergleichen: s[i][j] == 1 || s[i][j] == 2 .... Oder besser: if(s[i][j] >= 1 && s[i][j] <= 9) .

    Aber: Was soll dir das bringen? Das prüft doch nur, ob die Zahlen alle im erlaubten Bereich liegen. Mit deinem Problem hat das nichts zu tun.

    PS: Der beste Moment, dir globale Variablen abzugewöhnen, ist jetzt sofort!



  • bool checkRow( int y)
    {
       bool habbich[10]={false,false,false,false,false,false,false,false,false,false};
       for( int x = 0; x < 9; x++ )
       {
          //ganz falsche zahl oder 0
          if(s[y][x]<1 or s[y][x]>9) then 
             return false;
    
          //zahl doppelt
          if(habbich[x]==true) then
             return false;
    
          //zahl merken
          habbich[y][x]=true
       }
       //hab über die gesamte for-schleife keinen fehler nachweisen können. 
       return true;
    }
    


  • Ändere vielleicht die checkRow Funktion hier in eine check Version die einfach 9 Elemente annimmt und diese dann prüft. In der Funktion die check aufruft, muss du dann diese neun Elemente aus deiner Matrix zusammen stellen, also alle Zeilen, Spalten und dann die Teilmatrizen.



  • mal eine kleine nebenfrage?

    in zeile 57ff

    i = (i / 3) * 3 ;
          j = (j / 3) * 3 ;
    

    ist das nicht das gleiche wie i=i und j=j?



  • Mvstylez schrieb:

    mal eine kleine nebenfrage?

    in zeile 57ff

    i = (i / 3) * 3 ;
          j = (j / 3) * 3 ;
    

    ist das nicht das gleiche wie i=i und j=j?

    Nur wenn i oder j 0 oder ein vielfaches von 3 sind. Bei allen anderen Zahlen kommt aufgrund der Integer Division andere Zahlen bei raus.

    i = 2;
    i = (i / 3) * 3; // i ist dann 0
    i = 5;
    i = (i / 3) * 3; // i ist dann 3
    


  • ahh danke! ergibt sinn 😉


Anmelden zum Antworten