递归问题

时间:2013-11-10 04:08:45

标签: c++ recursion

我正在使用递归制作一个数独求解器,我遇到了一些问题。我在我的寓言和功能旁边放了评论,试图让它尽可能清晰。我的逻辑听起来像这样吗?我的代码中的其他所有内容都有效。它只是解算器/递归而不是。

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
}

2 个答案:

答案 0 :(得分:0)

您提供的solver函数实际上查看整个数组,并且 - 如果代码中使用的其他函数正常工作 - 应该实际解决这个难题。如果您将cout << " TRUE TRUE "<<endl;替换为cout << "["<<r<<"]["<<c<<"]: "<<i<<endl;,则会注意到所有索引都已被检查。

因此问题必须出在您未提供以下代码的3个函数中的任何一个:row_validcol_validpanel_valid

注意: 我不认为在这个特定问题中使用递归是一个好主意。您可能应该使用for来检查和解决电路板。这将更快更容易。

第一篇文章更新后编辑

row_validcol_valid函数不是很有效。您无法检查c !=i部分,因为它会使所有检查失败。将if语句更改为:

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

答案 1 :(得分:0)

截至您的评论回复,是:

正确编码。

使用应使用的方法并正确命名 InitilalizeBoard填写所有零 让SetBoard将起始值放在棋盘上 让SolveBoard尝试解决它。​​

这是一个很好的编程习惯,让每个方法做一件事,并使它的名字清晰。

话虽如此,几年前我做了类似的事情。使用for / while循环使用强制方法来解决数据变得更容易,更快,并且需要更少的代码,而不是使用递归,或者甚至将其编码为高效并尝试像人类一样解决它(删除明显错误的选项等等。)

所以,根据你的最终结果,你可能想要对它进行适当的编码......(我这样做是为了刷新我的C ++,所以没有先关心这么做很难,然后再做它简短的方法)。