Java 我的方法应该多次迭代,但它不是';t、 为什么??

Java 我的方法应该多次迭代,但它不是';t、 为什么??,java,recursion,methods,arraylist,sudoku,Java,Recursion,Methods,Arraylist,Sudoku,我正在写一个数独解题算法,我正在尝试实现一个演绎方法来解题。然而,我必须对递归之类的东西有一个松散的理解,因为我的算法似乎最多只改变一次电路板,即使我设置的条件大多数时候都应该返回true。以下是我的方法 public void CRME() { for (Node n : cells) { scanColumn(n); scanRow(n); scanMiniGrid(n); sortBoardVals(); }

我正在写一个数独解题算法,我正在尝试实现一个演绎方法来解题。然而,我必须对递归之类的东西有一个松散的理解,因为我的算法似乎最多只改变一次电路板,即使我设置的条件大多数时候都应该返回true。以下是我的方法

public void CRME() {
    for (Node n : cells) {
        scanColumn(n);
        scanRow(n);
        scanMiniGrid(n);
        sortBoardVals();
    }
}
这将扫描每列、每行和迷你网格,并在代表线路板的arraylist中剔除每个节点的可能值

    public void solve(){
    boolean canChange = false;
    ArrayList<Node> before = new ArrayList<Node>(cells);
    CRME();
    for(Node n : cells){
        int i = cells.indexOf(n);
        if(n.isEqual(before.get(i))){
            canChange = false;
        } else {
            canChange = true;
            break;
        }

    }
    if(canChange){
        System.out.println("Solving...");
        solve();
    }
}
public void solve(){
布尔canChange=false;
ArrayList before=新的ArrayList(单元格);
CRME();
用于(节点n:单元){
int i=单元格。indexOf(n);
如果(n.isEqual(在.get(i)之前))){
canChange=假;
}否则{
canChange=true;
打破
}
}
如果(可以更改){
System.out.println(“解决…”);
solve();
}
}
这是一个求解算法,它应该会自动调用,直到完全耗尽为止

这是我的节点类

public class Node {
public ArrayList<Integer> posVals = new ArrayList<Integer>(9) {{
    add(1);
    add(2);
    add(3);
    add(4);
    add(5);
    add(6);
    add(7);
    add(8);
    add(9);
}};
private int ROW_ID;
private int COL_ID;
private int MG_ID;
static boolean hasChanged = true;

int value = 0;

public boolean isEqual(Node n){
    if(this.posVals.size() == n.posVals.size()){
        return true;
    }
    else return false;
}
}
公共类节点{
public ArrayList posVals=新的ArrayList(9){{
增加(1);
增加(2);
增加(3);
增加(4);
增加(5);
增加(6);
增加(7);
增加(8);
增加(9);
}};
私人int ROW_ID;
私人国际学院;
私人内部管理ID;
静态布尔值hasChanged=true;
int值=0;
公共布尔相等(节点n){
if(this.posVals.size()==n.posVals.size()){
返回true;
}
否则返回false;
}
}
我可能会考虑重新思考我的项目,因为我认为使用arraylist会使问题过于复杂

CRME中的方法基本上扫描每个节点,找到包含相同列行和迷你网格的每个节点的值,并将它们从节点的可能值数组列表中删除

然后,sortboard values方法检查节点中的arraylist的大小是否为1,如果为1,则将该节点的值设置为arraylist中的最后一个值

    public void sortBoardVals() {
    for (Node n : cells) {
        if (n.posVals.size() == 1) {
            if (n.value == 0)
                n.value = n.posVals.get(0);
        }
    }
}

public void scanColumn(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_COL_ID() == n.get_COL_ID()) {
            toRemove.add(node.getValue());
        }

        n.posVals.removeAll(toRemove);

    }

}

public void scanRow(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_ROW_ID() == n.get_ROW_ID()) {
            toRemove.add(node.getValue());
        }

        n.posVals.removeAll(toRemove);

    }
}

public void scanMiniGrid(Node n) {
    for (Node node : cells) {
        ArrayList<Integer> toRemove = new ArrayList<Integer>();
        if (node.get_MG_ID() == n.get_MG_ID()) {
            toRemove.add(node.getValue());
        }
        n.posVals.removeAll(toRemove);
    }
}
public void sortBoardVals(){
用于(节点n:单元){
如果(n.posVals.size()==1){
如果(n.value==0)
n、 value=n.posVals.get(0);
}
}
}
公共void扫描列(节点n){
用于(节点:单元){
ArrayList toRemove=新建ArrayList();
if(node.get\u COL\u ID()==n.get\u COL\u ID()){
toRemove.add(node.getValue());
}
n、 位置移除所有(toRemove);
}
}
公共void扫描行(节点n){
用于(节点:单元){
ArrayList toRemove=新建ArrayList();
if(node.get_ROW_ID()==n.get_ROW_ID()){
toRemove.add(node.getValue());
}
n、 位置移除所有(toRemove);
}
}
公共网格(节点n){
用于(节点:单元){
ArrayList toRemove=新建ArrayList();
if(node.get\u-MG\u-ID()==n.get\u-MG\u-ID()){
toRemove.add(node.getValue());
}
n、 位置移除所有(toRemove);
}
}

在第二个窗格中,看起来您复制了单元格并将其称为“before”

然后比较单元格中的项目和之前的项目,因此在不知道CRME中的功能的情况下,简单的答案似乎是单元格和之前的项目是相等的

我也不知道你是怎么做的。你确实意识到,对于大多数未解决的数独游戏中的大量单元,其价值不会受到限制,对吗

我将首先设置一个除了一个单元格之外的完整谜题,然后在调试程序试图解决该单元格时,通过调试程序跟踪您的代码


因为节点数是恒定的,所以应该使用Node[]而不是ArrayList。类似地,您应该使用boolean[]而不是ArrayList来表示可能的值(对于每个值,true=可能,false=不可能),如果没有这样的想法,在我看来,我将不得不完全重新考虑数据结构,谢谢。@Saposhiente这是非常次要的东西。我看不出这两个改变会如何使这变得更容易。@JohnKugelman这不是一个解决方案,但它使它更有效。这就是为什么我把它作为一个评论,而不是一个答案。谢谢,如果我也给他们看的话会更清楚,现在是早上5点,我很累哈哈