我正在尝试实现一个boggle求解器。
我的基本想法是创建一种方法来检查单词是否在板上。然后通过删除以char不在板上的单词来修剪我的字典,然后将该方法应用于字典集上的每个单词以获得解决方案集。
我不完全确定这个解决方案的效率如何......我很确定它只是在O(n)上运行(与字典集的大小成比例) - 这对于更大的板子来说会很好(5x5 - 7x7)
我当前的方法(如果我可以修复访问的方式,它应该有效):
private Tile findFirstTile(String word) {
word = word.toUpperCase();
Tile first = null;
boolean found = false;
for (Tile tile : tiles) {
if (tile.getChar() == word.charAt(0)) {
first = tile;
found = true;
}
}
if (found) {
System.out.println("Found the tile!!");
return first;
}
else return null;
}
public boolean findWordOnBoard(String word, Tile tile, int depth, HashSet<Integer> visited) {
System.out.println("depth is " + String.valueOf(depth) + " right meow.");
if (depth == word.length()) return true; // base case - breaks recursion (on board)
else {
word = word.toUpperCase();
if (tile == null) return false;
HashSet<Integer> neighbors = map.get(tile.getPlace());
for (int n : neighbors) {
if ((tiles[n-1].getChar() == word.charAt(depth)) && (!visited.contains(n))) {
visited.add(n);
System.out.println("found " + tile.getChar() + " at " + n);
if (depth == word.length()) return true; // it shouldn't but oh well it's just here
findWordOnBoard(word, tiles[n-1], depth +1, visited);
}
}
System.out.println("only supposed to be here if it's ACTUALLY not on board");
return false; //will only get here if it doesn't find a new word
}
}
我不确定我是否正确实现了递归..它现在没有找到任何单词,但在我看来它应该有效..?我特别担心的是我是否正确处理了访问集(如果它正在跟踪每个深度访问的哪些图块),但我知道这不是唯一的问题,因为我仍然可以找到一些简短的单词。 ..
R L O S
E E A P
M S T R
E A T S
另外,我刚刚意识到我的“findFirstTile”方法只会开始在最后一个以该字母开头的图块上查找单词...所以如果在板上多次出现该字母,它可能无法查看全部它们。
这也是我的Tile对象的构造函数:
public Tile (char letter, int place){ // NOTE: the char MUST BE capital
this.letter = letter;
this.place = place;
try {
img = ImageIO.read(new File("tile"+letter+".png"));
} catch (IOException e) {
}
我引用的Tile数组(tile)也只是按顺序排列所有tile的数组 所以基本上在我的董事会上:
tiles[0] tiles[1] tiles[2] tiles[3]
tiles[4] tiles[5] tiles[6] tiles[7]
tiles[8] tiles[9] tiles[10] tiles[11]
tiles[12] tiles[13] tiles[14] tiles[15]
而“places”(来自Tile构造函数)只是
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
我已经检查了我的getNeighbors()和getChar()以及getPlace()方法,它们都按预期工作。
答案 0 :(得分:2)
如果有人想知道(可能不是,哈哈)
这是经过修订(和工作)的代码:
public boolean findWordOnBoard(String word, Tile tile, int depth, HashSet<Integer> visited) {
if (depth == word.length()) return true; // base case - breaks recursion (on board)
else {
word = word.toUpperCase();
if (tile == null) return false;
HashSet<Integer> neighbors = map.get(tile.getPlace());
for (int n : neighbors) {
if (depth >= word.length()) return true;
if ((tiles[n-1].getChar() == word.charAt(depth)) && (!visited.contains(n))) {
visited.add(n);
System.out.println("found " + tile.getChar() + " at " + n);
return findWordOnBoard(word, tiles[n-1], depth+1, visited);
}
}
}
return false; //will only get here if it doesn't find a new word
}
问题只是返回递归调用,而不是只是让它,因为当它通过递归向后返回基础案例调用break(depth == word.length()) 当深度回到1时,它停止了。