广度优先搜索不起作用

时间:2014-12-06 06:32:49

标签: java algorithm search tree

我正构建一个游戏,我在其中构建一个单词哈希表(一个字典),然后从用户那里获取两个字符串和一个int。我尝试将第一个字符串置换为第二个字符串。这是通过一次置换一个字母并将新单词作为子节点放入树结构中来保存原始单词来完成的。这样做直到原始单词成功置换到第二个单词或直到数字排列超过用户给出的int。在我的基本测试案例中,我给程序猫和婴儿床和3个啤酒花。这不起作用。我已经尝试了几件事,但在这一点上,我真的无法弄清楚任何事情,而且可以更具体。这是代码

public static void permute(HashTable dict, Queue<TNode> nodes, ArrayList<String> oldWords, String destination, int hops, int hopCounter) {
    char[] alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', //array with every letter in the alphabet will be used for permutations 
            'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    Queue<TNode> nextGen = new Queue<TNode>(); //holds the deepest generation of nodes
    TNode goalNode = null;//node to hold a successful node
    hopCounter++;
    boolean found = false;
    while (!nodes.empty()) {
        TNode parent = nodes.dequeue();
        oldWords.add(parent.getWord());
        for (int q = 0; q < parent.getWord().length(); q++) {
            char oldLet = parent.getWord().charAt(q);
            for (int i = 0; i < alphabet.length; i++) {
                String test = parent.getWord().replace(oldLet, alphabet[i]);
                if (dict.contains(test) && !oldWords.contains(test)) {
                    nextGen.enqueue(new TNode(test, parent, hopCounter));
                    found = test.equals(destination); //determine if successful permutation 
                    if (found) {
                        goalNode = new TNode(test);
                    }
                }

            }
        }
    }

    if (hopCounter < hops && !found) {
        permute(dict, nextGen, oldWords, destination, hops, hopCounter);
    } else {
        if (hopCounter == hops) {
            System.out.println("Unable to permute to " + destination + " in " + hops + " hops.");
        } else { //Successful, found = true
            StringBuilder path = new StringBuilder(goalNode.getWord());
            TNode currentNode = goalNode.getParent();
            for (int i = goalNode.getDepth() - 1; i > 0; i--) {
                path.insert(0, currentNode.getWord() + "==>");
            }
            System.out.println("Successful!");
            System.out.println(path.toString());
        }
    }
}

TNode只是一个节点,它有一个String,一个指向父节点的指针和一个用于节点在树中深度的int。 hops是用户给出的数字,hopCounter保存当前跃点。传递的原始队列包含具有原始单词的单个节点。 oldWords包含已经创建的所有排列,因此我可以避免重复。

我可能会说这一切都错了但是没有一种好的方法可以测试它是否真的有效。如果有更好的方法来测试和调试循环中运行这么多次将会有所帮助。我使用过调试器,但它们对此没有帮助。任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:0)

好吧,对于其中一个,parent.getWord().replace(oldLet, alphabet[i])使用不同的字母替换所有出现的oldLet,而不仅仅是q位置。

此外,在输出结果时,您不会更新currentNode。我写了像

这样的东西
while (currentNode != null) {
    path.insert(0, currentNode.getWord() + "==>");
    currentNode = currentNode.getParent();
}

当然,这假定根节点的父节点是null

作为一个侧面评论,为了提高性能,我将HashTable用于oldWords,因为ArrayList.contains是O(n)操作。