草庐IT

c++ - 数独递归回溯,反递归太早

coder 2024-02-26 原文

所以我正在用 C++ 编写数独解算器,但遇到了一些小问题。下面是我的解决板代码。它适用于拼图的前 3 行,但在到达第 4 行末尾时不再递归。查看 gdb 上的代码,它到达第 4 行的末尾,回溯到第 6 列,尝试然后反递归到最后。

关于代码的其他一些注意事项是保存数独板的矩阵从 1,1 而不是 0,0 开始。因此,当最初调用 solveBoard 时,参数为 (1, 1, 0)。我还附上了 setCell 和 checkConflicts 函数以获得更多信息。我有三个 vector rowConf、colConf 和 squConf 来存储已经放置在相应行、列或正方形中的值。我已经在这几个小时了,无法让它超过第三排。非常感谢任何帮助。谢谢!

编辑:添加了 clearCell()

bool board::solveBoard(int i, int j, int count)
{

    if (j > 9)
    {
        j = 1;
        i++;

        printBoard();
        if (isSolved())
        {
            printBoard();
            cout <<"The Board has been solved!" <<endl
                 <<" The number of recursive calls was: " <<count <<endl;
            return true;
        }
     }

     if (isBlank(i, j))
     {
         for (int n = 1; n < 10; n++)
         {
             if (setCell(i, j, (char)n + '0'))
             {
                 if (solveBoard(i, j + 1, count + 1))
                 {
                     return true;
                 }
              }
          }
      }
      else
      {
          return (solveBoard(i, j + 1, count + 1));
      }

      clearCell(i, j);
      return false;
}

bool board::setCell(int i, int j, char val)
{
    int intVal;

    intVal = atoi(&val);

    if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize &&
        intVal >= 1 && intVal <= BoardSize)
    {
        if (!(checkConflicts(intVal, i, j, squareNumber(i, j))))
        {
        return false;
        }

        value[i][j] = intVal;

        // Set flags of the conflicts
        rowConf[i][intVal] = true;
        colConf[j][intVal] = true;
        squConf[squareNumber(i, j)][intVal] = true;

        return true;
    }
    else
    {
        throw rangeError("bad value in setCell");
    }
}

bool board::checkConflicts(int val, int i, int j, int k)
{
    if (i < 1 && i > BoardSize && j < 1 && j > BoardSize &&
        k < 1 && k > BoardSize && val < 1 && val > BoardSize)
    {
        throw rangeError("bad value in checkConflicts()");
    }

    if (rowConf[i][val] || colConf[j][val] || squConf[k][val])
    {
        return false;
    }
    else
    {
        return true;
    }
}

Initial Board:
 -----------------------------
| 3       |    8    |          -----------------------------
|         | 7       |       5  -----------------------------
| 1       |         |          ----------------------------- 
 -----------------------------
|         |         | 3  6     -----------------------------
|       2 |       4 |          -----------------------------
|    7    |         |          -----------------------------
 -----------------------------
|         |    6    | 1  3     -----------------------------
|    4  5 | 2       |          -----------------------------
|         |         | 8        -----------------------------
 -----------------------------

Final Output:
 -----------------------------
| 3  2  4 | 1  8  5 | 6  7  9  -----------------------------
| 6  8  9 | 7  2  3 | 4  1  5  -----------------------------
| 1  5  7 | 4  9  6 | 2  8  3  -----------------------------
 -----------------------------
|         |         | 3  6     -----------------------------
|       2 |       4 |          -----------------------------
|    7    |         |          -----------------------------
 -----------------------------
|         |    6    | 1  3     -----------------------------
|    4  5 | 2       |          -----------------------------
|         |         | 8        -----------------------------
 -----------------------------

void board::clearCell(int i, int j)
{
    int intVal;

    if (i >= 1 && i <= BoardSize && j >= 1 && j <= BoardSize)
    {
        if (value[i][j] != -1)
        {
            intVal = value[i][j];
            rowConf[i][intVal] = false;
            colConf[j][intVal] = false;
            squConf[squareNumber(i, j)][intVal] = false;
            value[i][j] = -1;
         }
    }
    else
    {
        throw rangeError("bad value in setCell");
    }
}

最佳答案

您的问题很可能在这里:

if (isBlank(i, j))
 {
     for (int n = 1; n < 10; n++)
     {
         if (setCell(i, j, (char)n + '0'))
         {
             if (solveBoard(i, j + 1, count + 1))
             {
                 return true;
             }
          }
      }
  }

它以某种方式通过了这个部分,这就是为什么它最终没有通过 else,但由于之前没有返回,它被卡住了。

这需要更多的调试,但这里有一个可能导致解决方案的想法:

if (isBlank(i, j))
{
    for (int n = 1; n < 10; n++)
    {
        if (setCell(i, j, (char)n + '0'))
        {
            if (solveBoard(i, j + 1, count + 1))
            {
                return true;
            } else {
                echo 'Looks like it ended on the farthest-level..';
          } 
      } else {
          echo 'Looks like it ended on the second-farthest level.';
      }
  }

关于c++ - 数独递归回溯,反递归太早,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13215823/

有关c++ - 数独递归回溯,反递归太早的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  3. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  4. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  5. ruby - 递归地将所有数字字符串转换为 Ruby 哈希中的整数 - 2

    我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj

  6. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  7. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  8. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  9. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

  10. ruby - 为什么我用递归得到 "stack level too deep"? - 2

    我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大

随机推荐