递归单词搜索算法
现在是我为你祖母编写她的第一个 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)
It's time for me to write your grandmother her first Java word search program. But instead of having her do all the work by looking for words within the letter grid, a recursive function 4WaySearch
does it for her!
The only problem is:
I am finding it hard to conceptualize a recursive algorithm that builds every possible letter combination when starting at once place in the grid.
Here's code I already have written that I deem a big step in the right direction:
/*
* 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()
);
}
In my head, I visualize the search algorithm just like a recursive tree traveral algorithm, but each node (entry in this case) has 4 children (tangent entrys), and the leaf nodes are the boundaries of the grid.
Also, the location of the cursor upon initial entry into the function is determined by a simple for loop psuedocoded here:
for (int r = 0; r < ROWS; r++)
for (int c = 0; r < COLS; c++)
4WaySearch(r,c);
end for;
end for;
I have been thinking about this for a while now, and trying different approaches... but I still cant seem to wrap my mind around it and make it work. Can someone show me the light? (For the sake of me and your grandmother! :D)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我要做的是建立一个树结构。节点的定义如下
每次当你有一个新的起始位置时,你想要为树创建一个新的根节点
然后你想要构建树
这可能不是最好的方法,但对我来说它看起来简单易懂。
What I would do is build a Tree structure. Where a Node is defined like so
Each time you have a new starting place you want to create a new root node for the tree
And then you want to build the tree as you go
This might not be the best way to do it but to me it seems simple and easy to follow.
所以你需要做的就是首先建立网格。在本例中,您选择了 3x3 。您需要的是一种跟踪网格上所有有效点的方法,我可以推荐一个名为
Point
的对象,它采用两个int
作为其构造函数。接下来您需要一个由Point
和char
组成的类,这将使我们能够查看每个Point
处可用的字母代码> .现在我们已经有了数据结构,我们需要跟踪游戏的有效动作。例如,如果我位于位置 3,3(右下角,或者 2,2,如果你是零基础),我需要意识到我唯一有效的移动是向上或向左。确定这一点的方法是保留一个
Set
的Point
来告诉我所有我访问过的地方,这将使递归算法终止。一些可能有帮助的递归伪代码
So what you need to do is first establish the grid. In this instance you have elected for 3x3 . What you need is a way to keep track of all the valid points on the grid, might I recommend an object called
Point
that takes twoint
s as its constructor. The next thing you need is a class that is composed of aPoint
and achar
, this will enable us to see what letter is available at eachPoint
.Now that we have our data structure in place we need to keep track of valid moves for the game. For instance if I am at position 3,3 (the bottom right corner, or 2,2 if you are zero based) I would need to realize that the only valid moves I have are up or left. The way to determine this is to keep a
Set
ofPoint
s that tell me all the places I have visited, this will enable the recursive algorithm to terminate.Some pseudocode for the recursion that may help
我认为树是可行的方法,但与其他答案似乎使用它的方式不同。
我要做的是建立一个你正在寻找的单词的解析树(从字典中)——每个字母都是一个节点,有 26 个可能的子节点,每个字母对应一个字母表(检查
null
子元素在递归之前),以及一个表示它是否是完整单词的标志。检查每个方向,看看你是否可以朝那个方向移动,并相应地移动。我想说最困难的部分是构建树,它不应该递归地完成,但我只是有另一个想法。构建树的最佳方法也是递归。
这显然只是一个概述,但希望足以给您一个开始。如果您再次陷入困境,请发表评论,我会看看是否可以将您推向正确的方向。
I think a tree is the way to go, but not in the way other answers seem to be using it.
What I would do would be to build a parse tree of the words you're looking for (from the dictionary) -- each letter is a node, with 26 possible children, one for each letter of the alphabet (check for
null
children before recursing), and a flag saying whether it's a complete word. Check each direction, see if you can move in that direction, and move accordingly.I was going to say that the hard part would be building the tree and it shouldn't be done recursively, but I just had another thought. The best way to build the tree is also recursive.
This is obviously just an overview, but hopefully enough to give you a start. If you get stuck again, comment and I'll see if I can push you more in the right direction.