0

再帰を使用して数独ソルバーを作成していますが、いくつか問題があります。これをできるだけ明確にするために、変数と関数の横にコメントを入れました。私の論理はこれがうまくいくように聞こえますか? 私のコードの他のすべてが機能します。そうでないのは、ソルバー/再帰だけです。

bo


boourn 
    f nt j=0; j < 9; j++)
    rowc c=0;
           8) //if row is past 8 then the board is done

            return true;


    for (int < 10; i++)
    {

                    nextr r; //save next row and col
                    next;
                    tcol++; /ncrement next col and row
                     (nextcol >8) {
                nextcol =0;
                nx
            if(ncol==0 && nextrow ==9)
    r(0, 0
}
4

2 に答える 2

0

solverあなたが提供した関数は実際に配列全体を表示し、コードで使用されている他の関数が正しく機能していれば、実際にパズルを解決する必要があります。を置き換えるcout << " TRUE TRUE "<<endl;cout << "["<<r<<"]["<<c<<"]: "<<i<<endl;、すべてのインデックスがチェックされていることがわかります。

したがって、問題は、コードを提供しなかった 3 つの関数のいずれかにあるに違いありません: row_validcol_validまたはpanel_valid.

注: この特定の問題で再帰を使用することは良い考えではないと思います。forボードを確認して解決するには、おそらく a を使用して実行する必要があります。その方が速くて簡単です。

最初の投稿が更新された後に編集

および関数はまったく有効ではありませんrow_valid。すべてのチェックが偽になるため、パーツをcol_validチェックすることはできません。c !=iif ステートメントを次のように変更します。

if (v == rowcol[i][c] && v!=0)

if (v == rowcol[r][j] && v!=0)

また、少し変更する必要がありsolverます:

bool sudoku :: solver(int r, int c) {
   while( r < 9 && rowcol[r][c] !=0) {
    c++;
    if ( c>8) {
        c=0;
        r++;
    }
    if (r > 8) {
        return true;
    }
  }
  for (int i=1; i < 10; i++)
  {
    int nextrow, nextcol;
      if (row_valid (r, c, i)&& col_valid(r, c, i)&& panel_valid(r,c, i)) {
        rowcol[r][c]=i;
        nextrow=r; //save next row and col
        nextcol=c;
        nextcol++; //increment next col and row
        if (nextcol >8) {
            nextcol =0;
            nextrow++;
        }
        if(nextcol==0 && nextrow ==9) {
            return true; //then it's done
        }
        if (solver(nextrow,nextcol)) {
            return true;
        }
        else{
            rowcol[r][c]=0;
        }
      }
   }
   return false;
}

これは私にとってはうまくいくようで、次の出力が得られます。

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 1 4 3 6 5 8 9 7
3 6 5 8 9 7 2 1 4
8 9 7 2 1 4 3 6 5
5 3 1 6 4 2 9 7 8
6 4 2 9 7 8 5 3 1
9 7 8 5 3 1 6 4 2
于 2013-11-10T04:29:27.273 に答える
0

あなたのコメント返信の時点で、はい:

適切にコーディングしてください。

使用すべきメソッドを使用し、適切な名前を付けます。すべてのゼロを埋めて
ください。 ボードに開始値を配置しました。それを解決してみてください 。InitilalizeBoard
SetBoard
SolveBoard

各メソッドに 1 つのことをさせ、その名前を明確にすることは、プログラミングの良い習慣です。

そうは言っても、私は数年前に似たようなことをしました。for/while ループを使用してブルート フォース アプローチで数独を解く方が、再帰を使用したり、効率的にコーディングして人間のように解こうとしたりするよりも、はるかに簡単で高速で、必要なコードも少なくて済みます (オプションを削除してください)。明らかに間違っているなど)。

したがって、最終結果に応じて、適切にコーディングすることをお勧めします...(私はC ++を更新するためにそれを行ったので、最初に困難で長い方法を実行してから、短い方法で実行することを気にしませんでした)。

于 2013-11-10T04:36:27.697 に答える