2011-10-24 9 views
1

低レベルコースでの割り当てとして再帰を扱うのは初めてのことです。私はインターネットの周りを見てきました。私は思いついた方法に似た方法を使っている人がいないように見えます。エラーは、私が仮定しているstd::__copy_move...のセグメンテーション違反です.C++ STLの中に何かがあります。次のように とにかく、私のコードは次のとおりです。再帰バックトラック数独ソルバー問題、C++

bool sudoku::valid(int x, int y, int value) 
{ 
    if (x < 0) {cerr << "No valid values exist./n";} 

    if (binary_search(row(x).begin(), row(x).end(), value)) 
     {return false;}     //if found in row x, exit, otherwise: 
    else if (binary_search(col(y).begin(), col(y).end(), value)) 
     {return false;}     //if found in col y, exit, otherwise: 
    else if (binary_search(box((x/3), (y/3)).begin(), box((x/3), (y/3)).end(), value)) 
     {return false;}     //if found in box x,y, exit, otherwise: 
    else 
     {return true;}     //the value is valid at this index 
} 

int sudoku::setval(int x, int y, int val) 
{ 
    if (y < 0 && x > 0) {x--; y = 9;} //if y gets decremented past 0 go to previous row. 
    if (y > 8) {y %= 9; x++;}   //if y get incremented past 8 go to next row. 

    if (x == 9) {return 0;}    //base case, puzzle done. 
    else { 
     if (valid(x,y,val)){   //if the input is valid 
      matrix[x][y] = val;   //set the element equal to val 
      setval(x,y++,val);   //go to next element 
     } 
     else { 
      setval(x,y,val++);   //otherwise increment val 
      if(val > 9) {val = value(x,y--); setval(x,y--,val++); } 
     }        //if val gets above 9, set val to prev element, 
    }         //and increment the last element until valid and start over 
} 

私はしばらくの間、この事のまわりで私の頭をラップしようとしてきたと私は間違って何が起こっているのかを把握するように見えることはできません。どんな提案も高く評価されています! :)

+0

「マトリックス」とは何ですか?そのような詳細を知らなくても、コードをデバッグするのは難しいです。 – Flexo

+1

私はあなたがアルゴリズムの設計を見直すべきだと思います。あなたの再帰の 'if'部分では、' else'部分で、再帰の前に妥当性をチェックし、妥当性検査をしません。また、再帰の後でのみ 'val> 9 'をチェックします。 – arne

+0

は、setvalとは何かを書くことから始まります。 (x、y、val)は、他の(x、y)pairesで何度もvalを代入しようとしますが、それが(x、y)で有効でない場合はどうなりますか? – lkanab

答えて

0

以下は、WindowsではないUnixのすべてです。

std::__copy_move...はSTLです。しかし、STLはそれ自身では何もしません。あなたのコードからのいくつかの関数呼び出しは、間違った引数や間違った状態で呼び出すでしょう。あなたはそれを理解する必要があります。

コア・ダンプが発生してからpstack <core file name>を実行すると、クラッシュの完全なコール・スタックが表示されます。次に、あなたのコードのどの部分がそれに関わっているかを見て、そこからデバッグを開始します(トレース/クエスト/ ...を追加します)。

通常、このコアファイルは読みやすい名前で表示されますが、そうでない場合は、dismanglenmまたはc++filtなどを使用できます。

最後に、pstackは常にあなたのIDEに組み込まれてgdbSun Studioやデバッガなどのデバッガにバイナリ(コアを生産している)と、コアファイルをロードし、一緒に同じものを見ることができ、ほんの少しのCMDラインユーティリティです他の情報やオプションがたくさんあります。

HTH

1

sudoku::setvalintを返すことになったが、それは全く何も返さない、少なくとも2つの経路が存在しています。他のパスで何を返す必要があるのか​​を理解する必要があります。そうしないと、未定義のランダムな動作が発生します。

1

これ以上の情報がなければ、わかりません。データが のようなものがあり、たとえばrowcolが返されます。 はまだ、明らかに多くの問題があります。sudoku::valid

  • 、あなたは明らかに誤り 条件(x < 0)何であるかをチェックしていますが、戻りません。負の値xを使用して、 テストを続行します。

    sudoku:validでも
  • rowcolは本当に ソート値への参照を返すのですか?値がソートされていない場合は、binary_search は未定義の動作をします(存在する場合、名前は多少 となります)。同じオブジェクトへの参照よりもむしろ という値(戻り値)が返された場合、begin()end() の関数は異なるオブジェクト—を再度参照し、定義されていない の動作を参照します。

  • 最後に、アルゴリズムでバックトラックが表示されず、 解決方法を確認できません。

FWIW:私は同様の何かを書いたとき、私は適切な行、列、およびボックスに インデックス(0 – 80)にマッピングされた静的配列を作成し、その後、基板81個の 要素の単純な配列を使用。 の9つの行、列、ボックスのそれぞれについて、使用済みの値のセットを保持しました( ビットマップ)。これは合法性のチェックを非常に些細なものにしていたことを意味し、 インデックスを増分するだけで、次の正方形まで増やすことができました。結果のコードは非常に簡単でした。独立し、あなたが必要と使用されるデータ表現の

:いくつかの 「グローバル」( sudokuのおそらくメンバーは)あなたが が解決策かどうかを見つけたかどうかを知ることの意味します。正方形(解が になったときに停止する)と再帰の可能な値のそれぞれを試みるどこかのループ。 ボード用のシンプルな配列を使用していない場合は、インデックスのクラスまたは構造体をお勧めします。 関数を使用すると、増分を一度に処理することができます。

0

関数を再帰的に何回も入力すると、セグメンテーションフォールトが発生する可能性があります。 私はそれにつながるシナリオに注目しました。しかし、私はもっと確信しています。

ヒント:あなたの言葉で任意の関数の目的を書く - それを書くのはあまりにも複雑である場合 - 機能は、おそらく分割すべき...

0

は、あなたのアルゴリズムは、ビット「ブルートforcy」であるように思えます。これは一般的に制約充足問題(Constraint Satisfaction Problems、CSPs)との良好な戦術ではありません。私は(私はgithubのを発見する前にそれがあった、私はまだソースコードがあればいいのに)しばらく前にソルバー数独を書いて、私は見つけることができる最速のアルゴリズムは、シミュレーテッドアニーリングだった:それは確率的だ

http://en.wikipedia.org/wiki/Simulated_annealing

、それこの問題IIRCの他の方法よりも一般的に数桁速かった。

HTH!