单词解算器 - 所有方向
我创建了一个适用于所有方向的单词解算器。它可以水平、垂直和反向查找单词。然而,我在让它朝各个方向发展时遇到了问题。因此,将“你好”纳入:
H E i l
x L p q
c L O m
任何人都可以指出我该怎么做吗?这是我搜索单词的算法(在 C++ 中):
/*
* For loops that search each row, each column in all 8 possible directions.
*/
void Scramble::solve() {
cout << "Output:" << endl;
for (int row = 0; row < getRows(); row++) {
for (int col = 0; col < getCols(); col++)
for (int rowDir = -1; rowDir <= 1; rowDir++)
for (int colDir = -1; colDir <=1; colDir++)
if (rowDir != 0 || colDir != 0)
findWords(row, col, rowDir, colDir);
}
}
/*
* Finds the matches in a given direction. Also calls verifyWord() to verify that the
* current sequence of letters could possibly form a word. If not, search stops.
*/
void Scramble::findWords(int startingRow, int startingCol, int rowDir, int colDir) {
int searchResult;
string sequence = "";
sequence = sequence + wordsArr[startingRow][startingCol];
for (int i = startingRow + rowDir, j = startingCol + colDir; i >= 0 && j >= 0
&& i < getRows() && j < getCols(); i = i + rowDir, j = j + colDir) {
sequence = sequence + wordsArr[i][j];
if (sequence.length() >= 3) {
searchResult = verifyWord(words, sequence);
if ((unsigned int)searchResult == words.size())
break;
if (words[searchResult].rfind(sequence) > words[searchResult].length())
break;
if (words[searchResult] == (sequence))
cout << sequence << endl;
}
}
}
/*
* Performs the verifyWord search method.
* Searches the word to make sure that so far, there is possibly that the current sequence
* of letter could form a word. That is to avoid continuing to search for a word
* when the first sequence of characters do not construct a valid word in the dictionary.
*
* For example, if we have 'xzt', when this search is done it prevents the search
* to continue since no word in the dictionary starts with 'xzt'
*/
int Scramble::verifyWord(vector<string> words, string str) {
int low = 0;
int mid = 0;
int high = words.size();
while (low < high) {
mid = (low + high) / 2;
if (str > words[mid]) {
low = mid + 1;
}
else if (str < words[mid]) {
high = mid - 1;
}
else
return mid;
}
}
I created a word solver for all directions. It finds words horizontally, vertically and reverse. However, I am having problems making it go all directions. So to take "hello" in:
H E i l
x L p q
c L O m
Anyone can point me on how to do that? Here is my algorithm to that searches for the words (in C++):
/*
* For loops that search each row, each column in all 8 possible directions.
*/
void Scramble::solve() {
cout << "Output:" << endl;
for (int row = 0; row < getRows(); row++) {
for (int col = 0; col < getCols(); col++)
for (int rowDir = -1; rowDir <= 1; rowDir++)
for (int colDir = -1; colDir <=1; colDir++)
if (rowDir != 0 || colDir != 0)
findWords(row, col, rowDir, colDir);
}
}
/*
* Finds the matches in a given direction. Also calls verifyWord() to verify that the
* current sequence of letters could possibly form a word. If not, search stops.
*/
void Scramble::findWords(int startingRow, int startingCol, int rowDir, int colDir) {
int searchResult;
string sequence = "";
sequence = sequence + wordsArr[startingRow][startingCol];
for (int i = startingRow + rowDir, j = startingCol + colDir; i >= 0 && j >= 0
&& i < getRows() && j < getCols(); i = i + rowDir, j = j + colDir) {
sequence = sequence + wordsArr[i][j];
if (sequence.length() >= 3) {
searchResult = verifyWord(words, sequence);
if ((unsigned int)searchResult == words.size())
break;
if (words[searchResult].rfind(sequence) > words[searchResult].length())
break;
if (words[searchResult] == (sequence))
cout << sequence << endl;
}
}
}
/*
* Performs the verifyWord search method.
* Searches the word to make sure that so far, there is possibly that the current sequence
* of letter could form a word. That is to avoid continuing to search for a word
* when the first sequence of characters do not construct a valid word in the dictionary.
*
* For example, if we have 'xzt', when this search is done it prevents the search
* to continue since no word in the dictionary starts with 'xzt'
*/
int Scramble::verifyWord(vector<string> words, string str) {
int low = 0;
int mid = 0;
int high = words.size();
while (low < high) {
mid = (low + high) / 2;
if (str > words[mid]) {
low = mid + 1;
}
else if (str < words[mid]) {
high = mid - 1;
}
else
return mid;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个有趣的思考方式:找到这个词就像解决迷宫一样。 “开始”和“结束”对应于您要查找的单词的开头和结尾,“死胡同”对应于路径和您的单词之间的不匹配,“成功”是当字符串沿着您的路径时是一场比赛。
好消息是有很多关于迷宫求解算法的资源。我熟悉的一种特殊算法,并且实现起来并不太困难,它是 带回溯的递归。
显然,必须进行一些更改才能解决您的问题。例如,您不知道从哪里开始,但幸运的是这并不重要。您可以检查每个可能的起始位置,其中许多位置无论如何都会由于不匹配而在第一步中被丢弃。
Here's an interesting way to think about it: finding the word is akin to solving a maze. The 'start' and 'end' correspond to the beginning and end of the word you're looking for, a 'dead end' corresponds to a mismatch between the path and your word, and 'success' is when the string along your path is a match.
The good news here is that there are lots of resources on maze-solving algorithms. One particular algorithm that I'm familiar with, and isn't too difficult to implement, is recursion with backtracking.
Obviously some changes will have to be made in order for this to work for your problem. You don't know where the start is, for example, but luckily it doesn't matter. You can check every possible starting position, and many of them will be discarded on the first step anyway due to a mismatch.
1) 目前,您的
solve()
函数从每个点开始在一条直线中查找单词:这是您想要的吗?我只是问,因为“你好”在你的样本矩阵中没有显示为直线:如果你确实想要直线单词,那么很好(这就是我一直理解这些谜题无论如何都可以工作),但如果实际上你想在蛇中找到单词-明智的时尚,然后像 Zilchonum 和 BlueRaja 这样的递归搜索建议将是一个不错的选择。只是要小心,不要最终循环回到已经使用过的字母。
2) 无论哪种情况,您的 verifyWord() 函数也存在一些问题:至少在退出 while (low < high) 的情况下它需要返回一些值循环。
即便如此,它仍然无法完全按照您想要的方式执行:例如,说您的字典
包含
{"ant", "bat" "hello", "yak", "zoo"}
,并且您使用str="hel 调用
,您希望返回值 2,但目前它是这样做的:verifyWord()
"与其将“hel”与“hello”进行比较,也许您最好将字典中的单词截断为与 str 长度相同:即比较
str
到word[mid].substr(0,str.length())
?1) Currently, your
solve()
function looks for a word in a straight line starting at each point: is this what you intend? I only ask because 'hello' doesn't appear as a straight line in your sample matrix:If you do want straight-line words only, then fine (this is how I've always understood these puzzles to work anyway), but if in fact you want to find words in a snake-wise fashion, then a recursive search like Zilchonum and BlueRaja are suggesting would be a good bet. Just be careful you don't end up looping back on letters you've already used.
2) In either case, your
verifyWord()
function also has some problems: at the very least it needs to return some value in the case where you exit thewhile (low < high)
loop.Even so, it still won't quite do what you want it to: for example, say your dictionary
contains
{"ant", "bat" "hello", "yak", "zoo"}
, and you callverifyWord()
withstr="hel"
, you'd like to return a value of 2, but at the moment it does this:Rather than comparing "hel" with "hello", perhaps you'd be better off truncating the words in the dictionary to the same length as str: ie comparing
str
toword[mid].substr(0,str.length())
?只需将其视为一个图表,其中每个字母都连接到所有相邻字母,并从每个字母开始进行深度/广度优先搜索,仅接受那些字母等于您要查找的下一个字母的节点。
Just treat it like a graph where each letter is connected to all adjacent letters, and do a depth/breadth-first search starting from each letter, only accepting those nodes whose letter is equal to the next letter you're looking for.
这是我写的一个简单的单词侦探程序 --->
在我的程序中,它首先检查单词的第一个字母,然后检查后续字母。如果找到该单词,则打印该单词的起始坐标以及找到该单词的方向。
This is a simple word sleuth program that i wrote --->
In my program, it first checks for the first letter of the word, and then the subsequent letters. If the word is found, then it prints the the starting coordinates of the word and the direction in which the word is found.