现在是时候给祖母写第一个Java字搜索程序了。但是,不是让她通过在字母网格中查找单词来完成所有工作,而是为她做一个递归函数4WaySearch
!
唯一的问题是:
我发现很难概念化一个递归算法,该算法在网格中一次性开始时构建每个可能的字母组合。
这是我已经写过的代码,我认为朝着正确的方向迈出了一大步:
/*
* This is the method that calls itself repeatedly to wander it's way
* through the grid using a 4 way pattern,
* creating every possibly letter combination and checking it against a
* dictionary. If the word is found in the dictionary, it gets added to a
* collection of found words.
*
* Here an example of a 3x3 grid with the valid words of RATZ and BRATZ, but
* the word CATZ isn't valid. (the C is not tangent to the A).
*
* CXY
* RAT
* BCZ
*
* @param row Current row position of cursor
* @param col Current column position of cursor
*/
private void 4WaySearch(int row, int col) {
// is cursor outside grid boundaries?
if (row < 0 || row > ROWS - 1 || col < 0 || col > COLS - 1)
return;
GridEntry<Character> entry = getGridEntry(row, col);
// has it been visited?
if (entry.hasBreadCrumb())
return;
// build current word
currentWord += entry.getElement(); // returns character
// if dictionay has the word add to found words list
if (dictionary.contains(currentWord))
foundWords.add(currentWord);
// add a mark to know we visited
entry.toggleCrumb();
// THIS CANT BE RIGHT
4WaySearch(row, col + 1); // check right
4WaySearch(row + 1, col); // check bottom
4WaySearch(row, col - 1); // check left
4WaySearch(row - 1, col); // check top
// unmark visited
entry.toggleCrumb();
// strip last character
if (currentWord.length() != 0)
currentWord = currentWord.substring(
0,
(currentWord.length() > 1) ?
currentWord.length() - 1 :
currentWord.length()
);
}
在我的脑海中,我将搜索算法可视化为递归树的几种算法,但每个节点(在这种情况下为条目)有4个子节点(切线托管),叶节点是网格的边界。
此外,光标在初始进入函数时的位置由一个简单的for循环伪装确定:
for (int r = 0; r < ROWS; r++)
for (int c = 0; r < COLS; c++)
4WaySearch(r,c);
end for;
end for;
我一直在思考这个问题,尝试不同的方法......但是我似乎仍然无法将其包裹起来并使其发挥作用。有人能给我看灯吗? (为了我和你的祖母!:D)
答案 0 :(得分:0)
所以你需要做的就是先建立网格。在这种情况下,您选择了3x3。你需要的是一种跟踪网格上所有有效点的方法,我可以推荐一个名为Point
的对象,它需要两个int
作为构造函数。接下来你需要的是一个由Point
和char
组成的类,这将使我们能够看到每个Point
可用的字母。
现在我们已经建立了数据结构,我们需要跟踪游戏的有效移动。例如,如果我在位置3,3(右下角,或者如果你基于零,则为2,2)我需要意识到我所拥有的唯一有效移动是向上或向左。确定这一点的方法是保留Set
个Point
告诉我所有访问过的地方,这将使递归算法终止。
可能有帮助的递归的一些伪代码
if(!validMovesRemaining)
return
else
removeValidPosition(pointToRemove);
captureLetter(composedObject);
recurse(pointsRemaining);
答案 1 :(得分:0)
我要做的是构建一个Tree结构。节点定义如此
public class Node {
private String data;
private int row,col;
private Node parent;
public Node(Node parent,int row,int col) {
this.parent = parent;
this.col = col;
this.row = row;
}
public boolean hasParent(int row, int col) {
Node current = this;
while((current=current.parent)!=null) {
if(current.row == row && current.col==col)
return true;
}
return false;
}
public String toString() {
Node current = this;
StringBuffer sb = new StringBuffer();
do {
sb.append(current.data);
}while((current = current.parent)!=null);
return sb.reverse().toString();
}
}
每次有新的起始位置时,都要为树创建新的根节点
for (int r = 0; r < ROWS; r++)
for (int c = 0; r < COLS; c++)
4WaySearch(new Node(null,r,c); //it is the root and has no parent
end for;
end for;
然后你想要随时建造树
private void FourWaySearch(Node c) {
if (c.row < 0 || c.row > ROWS - 1 || c.col < 0 || c.col > COLS - 1 || c.hasParent(c.row,c.col))
return;
else {
c.data = grid[c.row][c.col]; //get the string value from the word search grid
if(dictionary.contains(c.toString()))
foundWords.add(c.toString());
FourWaySearch(new Node(c,c.row-1,c.col));
FourWaySearch(new Node(c,c.row,c.col-1));
FourWaySearch(new Node(c,c.row+1,c.col));
FourWaySearch(new Node(c,c.row,c.col+1));
}
}
这可能不是最好的方法,但对我而言,这似乎很简单易懂。
答案 2 :(得分:0)
我认为树是可行的方式,但不是其他答案似乎在使用它的方式。 我要做的是构建一个你正在寻找的单词的解析树(来自字典) - 每个字母都是一个节点,有26个可能的孩子,每个字母对应一个字母(检查{{1}在递归之前的孩子),以及一个标志,说明它是否是一个完整的单词。检查每个方向,看看是否可以朝那个方向移动,并相应地移动。
我要说的是,困难的部分将是构建树,它不应该递归,但我只是有另一个想法。构建树的最佳方法也是递归的。
这显然只是一个概述,但希望足以为您提供一个开始。如果你再次陷入困境,请发表评论,我会看看能不能向你推进更多方向。