这是我第一次在低级课程中处理递归作为一项任务。我环顾了互联网,我似乎找不到任何人使用类似于我提出的方法(这可能说明了为什么这不起作用)。错误是std::__copy_move...
中的分段错误,我假设它是c ++ STL中的某些内容。
Anywho,我的代码如下:
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 :(得分:1)
sudoku::setval
应该返回一个int
,但至少有两个路径,它根本不返回任何内容。您应该弄清楚在其他路径中需要返回什么,否则您将获得随机未定义的行为。
答案 1 :(得分:1)
没有更多信息,就无法分辨。像数据这样的东西
例如,涉及的结构以及row
和col
返回的内容。
仍然存在许多明显的问题:
在sudoku::valid
中,您可以检查显然是错误的内容
条件(x < 0
),但你没有回来;你仍然继续你的
测试,使用x
的负值。
同样在sudoku:valid
:row
和col
确实返回了对
排序值?如果值未排序,那么binary_search
将会
有未定义的行为(如果它们是,名称有点
误导)。如果他们返回值(某些东西的副本),而不是
而不是对同一个对象的引用,那么begin()
和end()
函数将引用不同的对象 - 再次,undefined
行为。
最后,我没有看到你的算法有任何回溯,我没有 看看它如何发展成为一个解决方案。
FWIW:当我写了类似的东西时,我使用了81的简单数组 电路板的元素,然后创建映射的静态数组 索引(0-80)到适当的行,列和框。并为每一个 九行,列和框,我保留了一组使用过的值(a 位图);这使得检查合法性非常微不足道,这意味着 我可以通过递增来增加到下一个方格来测试 指数。结果代码非常简单。
无论使用何种数据表示,您都需要:一些
“全球”(可能是sudoku
的成员)意味着知道你是否已经
找到了解决方案;尝试九个中的每一个的某个循环
正方形的可能值(解决方案已停止时停止)
发现)和递归。如果你没有使用简单的数组
像我一样,我建议索引的类或结构,用
一劳永逸地处理增量的功能。
答案 2 :(得分:0)
以下所有内容适用于Unix而非Windows。
std::__copy_move...
是STL好的。但是STL本身并没有做任何事情,你的代码中的某些函数调用会用错误的参数或错误的状态调用它。你需要明白这一点。
如果您有来自teh seg-fault的核心转储,那么只需执行pstack <core file name>
,您将看到崩溃的完整调用堆栈。然后只需看看代码中涉及哪部分代码并从那里开始调试(添加trace / couts / ...)。
通常你会得到这个具有良好可读名称的核心文件,但如果你没有,你可以使用nm
或c++filt
等来dismangle这些名称。
最后,pstack
只是一个小的cmd行实用程序,您始终可以将二进制文件(生成核心)和核心文件加载到gdb,Sun Studio之类的调试器或调试器内置于您的IDE中,并查看相同的内容以及许多其他信息和选项。
HTH
答案 3 :(得分:0)
分段错误可能会(并且会发生)。 我注意到一个导致它的情景。但我很确定还有更多。
提示:在你的文字中写下任何函数的目的 - 如果它写得太复杂 - 函数应该被拆分......
答案 4 :(得分:0)
看起来你的算法有点“暴力”。这通常不是约束满意度问题(CSP)的好策略。我曾经写过一个数独求解器(希望我还有源代码,它是在我发现github之前),我能找到的最快算法是模拟退火:
http://en.wikipedia.org/wiki/Simulated_annealing
这是概率性的,但对于这个问题IIRC,它通常比其他方法快几个数量级。
HTH!