退出void递归Java函数的更平滑的方法
因此,我编写了这个函数,其行为类似于Knuth的算法X。仅用于说明-该函数需要一个可能行的大型矩阵,它试图在其中选择组成合法解决方案的行的组合 问题是,一旦我们找到了解决方案,因为它是空的,所以函数不会返回任何东西,而是返回(这意味着它会打印出递归深度中每一层的数独) 找到解决方案后,有没有关于如何结束函数的建议?我目前正在使用System.exit(0),但这并不好,因为程序会在您找到解决方案的那一刻结束(因此,您以后要做的任何事情都是不可能的-例如,在数独数组上运行函数并解决每个数独问题) 代码如下:退出void递归Java函数的更平滑的方法,java,recursion,Java,Recursion,因此,我编写了这个函数,其行为类似于Knuth的算法X。仅用于说明-该函数需要一个可能行的大型矩阵,它试图在其中选择组成合法解决方案的行的组合 问题是,一旦我们找到了解决方案,因为它是空的,所以函数不会返回任何东西,而是返回(这意味着它会打印出递归深度中每一层的数独) 找到解决方案后,有没有关于如何结束函数的建议?我目前正在使用System.exit(0),但这并不好,因为程序会在您找到解决方案的那一刻结束(因此,您以后要做的任何事情都是不可能的-例如,在数独数组上运行函数并解决每个数独问题)
public static void solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
System.exit(0);
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
solve(solution, coverMatrix);
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
}
}
publicstaticvoidsolve(arraylistsolution,arraylistcovermatrix){
if(Arrays.equals(solvedCase,workCase)){
//这意味着我们找到了解决方案
drawSudoku(testOutput);
系统出口(0);
}否则{
//找到我们尚未涉及的专栏
int NEXTCOLTOCOVERE=FindStartUnsativedConstraint(覆盖矩阵,工作用例);
//获取可能解决此问题的所有行
ArrayList行=匹配行(coverMatrix,NextColotCover);
//反复地试着把每一个都干掉
对于(int i=0;i
如果我理解正确,您希望在得到第一个解决方案时结束递归。您可以通过为方法使用布尔返回类型来实现这一点,并在获得第一个解决方案时返回true:
public static boolean solve(ArrayList<int[]> solution, ArrayList<int[]> coverMatrix) {
if (Arrays.equals(solvedCase, workCase)) {
//this means we found the solution
drawSudoku(testOutput);
return true;
} else {
//find the column we didnt yet cover
int nextColToCover = findSMARTUnsatisfiedConstraint(coverMatrix, workCase);
//get all the rows that MIGHT solve this problem
ArrayList<int[]> rows = matchingRows(coverMatrix, nextColToCover);
//recusively try going down every one of them
for (int i = 0; i < rows.size(); i++) {
//we try this row as solution
solution.add(rows.get(i));
//we remove other rows that cover same columns (and create backups as well)
removeOtherRowsAndAdjustSolutionSet(coverMatrix);
if (isSolutionPossible(coverMatrix)) {
boolean result = solve(solution, coverMatrix);
if(result == true) return result;//else continue
}
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
return false;
}
publicstaticbooleansolve(arraylistsolution,arraylistcovermatrix){
if(Arrays.equals(solvedCase,workCase)){
//这意味着我们找到了解决方案
drawSudoku(testOutput);
返回true;
}否则{
//找到我们尚未涉及的专栏
int NEXTCOLTOCOVERE=FindStartUnsativedConstraint(覆盖矩阵,工作用例);
//获取可能解决此问题的所有行
ArrayList行=匹配行(coverMatrix,NextColotCover);
//反复地试着把每一个都干掉
对于(int i=0;i
}您可以将
原子引用
类与布尔值
一起使用:
您可以这样调用您的方法(只需将
布尔值
初始化为false
):
publicstaticvoidmain(字符串[]args)
{
AtomicReference test1=新的AtomicReference();
test1.set(false);
求解(*,***,test1);
}
您可能会为此滥用异常的概念,尽管我不建议这样做
首先定义一个自定义异常类
public class SuccessException extends Exception {}
举出成功的例子
if (Arrays.equals(solvedCase, workCase)) {
drawSudoku(testOutput);
throw new SuccessException();
}
最初在try
块中调用函数
try {
solve(solution, coverMatrix);
} catch(SuccessException e) {
/* Solution found! */
}
您可能需要使用
return代码>查看我的答案它应该对您有效…函数返回void
,这是一项要求吗,或者它只需要两个参数?我会使用return,但是我在恢复covermatrix时会遇到问题-这样恢复会更方便-除非你能建议恢复部分,因为到目前为止,除了它之外,没有任何东西能起作用,因为它被认为是@rcn的。然后,如果解决了,则使solve return为真,并调整你的算法问题清楚通过添加一个返回类型声明它是一个void函数,您不再帮助OP解决问题。@StackFlowed该方法最初是无效的,因为OP不想返回任何有意义的“结果”,例如计算输出。但是,当他编写这个方法时,它处于完全控制之下,将void改为boolean并没有坏处,从而达到了预期的结果。还有一个副作用,它可以判断是否检测到任何“解决方案”。我会让OP决定是否要更改返回类型。我要指出的是,此时此刻你们并没有回答OP提出的问题。您回答了一个不同的问题,在这个问题中,您假设OP将更改返回类型。@StackFlowed ok,我将把它留给OP。但OP并没有特别提到他愿意改变方法返回类型,并不意味着他反对它。有时我们不得不从整体的角度来考虑问题,而不仅仅是“未完成”的解决方案。请阅读问题的标题退出无效递归Java函数的更平滑的方法
在所有这些参数之后,我仍然认为您的代码不起作用,因为您返回的是true,但没有使用该值。
if(!test.get())
{
// here the backtracking occurs if algorithm can't proceed
// if we the solution exists, do not rebuild the data structure
if (!Arrays.equals(solvedCase, workCase)) {
restoreTheCoverMatrix(coverMatrix);
}
}
public static void main(String[] args)
{
AtomicReference<Boolean> test1 = new AtomicReference<Boolean>();
test1.set(false);
solve(***, ***, test1);
}
public class SuccessException extends Exception {}
if (Arrays.equals(solvedCase, workCase)) {
drawSudoku(testOutput);
throw new SuccessException();
}
try {
solve(solution, coverMatrix);
} catch(SuccessException e) {
/* Solution found! */
}