递归回溯数独求解问题,c++
Recursive Backtracking Sudoku Solver Problems, c++
这是我第一次在低级课程中将递归作为作业来处理。我在互联网上四处寻找,似乎找不到任何人使用与我提出的方法类似的方法(这可能说明了为什么它不起作用)。错误是std::__copy_move...
的分割错误,我假设这是c++ STL中的一些东西。我的代码如下:
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
}
我一直想把我的头绕在这件事上一段时间,但我似乎不知道出了什么问题。任何建议都非常感谢!:) sudoku::setval
应该返回一个int
,但至少有两个路径它什么也不返回。你应该弄清楚它在其他路径中需要返回什么,否则你会得到随机的未定义行为
如果没有更多的信息,就无法判断。比如数据所涉及的结构,以及row
和col
返回的内容。尽管如此,还是有一些明显的问题:
-
在
sudoku::valid
中,您检查明显的错误条件(x < 0
),但你没有返回;你仍然继续你的测试,使用x
的负值。 -
同样在
sudoku:valid
:做row
和col
真的返回引用排序值吗?如果值没有排序,那么binary_search
将排序有未定义的行为(如果有,则名称有点?误导)。如果它们返回值(某些东西的副本),而是然后是begin()
和end()
函数将引用不同的对象—同样,未定义行为。 -
最后,我在你的算法中没有看到任何回溯,我也没有
顺便说一句:当我写类似的东西时,我使用了一个简单的81数组元素,然后创建静态数组来映射索引(0–80)到适当的行、列和框。对于每一个在九行、九列和九框中,我保存了一组使用值(a位图);这使得检查合法性变得微不足道,这意味着我可以增加到下一个平方来测试只需要增加索引。生成的代码非常简单。
与使用的数据表示无关,您将需要:some"global"(可能是sudoku
的成员)意味着知道您是否已经是否找到了解决方案;在某个地方循环尝试每一个一个正方形的可能值(当解已经find)和递归。如果不使用简单数组board,就像我做的那样,我建议为索引使用一个类或结构函数,一次性处理增量
以下所有内容适用于Unix而非Windows。
std::__copy_move...
是STL正确的。但STL本身不会做任何事情,代码中的一些函数调用会用错误的参数或错误的状态调用它。你得想清楚。
如果您有一个来自seg-fault的核心转储,那么只需执行pstack <core file name>
,您将看到崩溃的完整调用堆栈。然后看看你的代码哪一部分涉及到它,并从那里开始调试(添加跟踪/计数/…)。
通常你会得到这个核心文件与良好的可读性名称,但如果你不你可以使用nm
或c++filt
等拆除名称。
最后,pstack
只是一个小的cmd行实用程序,您可以随时将二进制文件(产生核心)和核心文件加载到调试器中,如gdb, Sun Studio或调试器内置到您的IDE中,并看到与许多其他信息和选项相同的东西。
HTH
看起来你的算法有点"蛮力"。这通常不是约束满足问题(csp)的好策略。我写了一个数独解算器(希望我仍然有源代码,这是在我发现github之前),我能找到的最快的算法是模拟退火:
http://en.wikipedia.org/wiki/Simulated_annealing这是概率性的,但它通常比这个问题的其他方法快几个数量级。
HTH !
如果多次递归地输入一个函数,可能(也将)发生分段错误。我注意到导致这种情况的一个场景。但我敢肯定还有更多。
提示:用你的语言写出任何函数的目的——如果它太复杂而写不出来——函数可能应该被拆分…
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 基于boost的程序的静态链接——zlib问题
- C++格式化输出问题
- 使用mongocxx驱动程序时包含头文件问题