我有一个Java学校项目,我也被分配了。现在我遇到了项目的一部分问题,我无法弄清楚。 应用程序必须从二维char数组(char [] []板)生成所有可能的单词组合(可以通过字典验证)。该板是动态的,因为用户可以选择比例:4x4,5x5,4x5,5x4,4x6,......所以我想这里的嵌套循环不会适用,如果我错了,请纠正我。必须水平,垂直和对角地生成单词。 4x4板的示例:
|你的a |你的s |
| n | n |我|我|
| a | o | e | b |
| e |你的e | z |
Code was completely wrong.
另一个想法可能是对电路板上的每条可能路径进行暴力破解,然后尝试这些保存的路径来验证它是否是一个字。
提前致谢!
答案 0 :(得分:2)
解决此问题的一种方法是:
for each path on the board
if corresponding word in dictionary
print it
要查找所有路径,您可以调整任何graph traversal algorithm。
现在这将是非常缓慢的,因为有很多板尺寸的路径(对于具有n个单元的板,我们最多可以有n * 4 ^ (n - 1)
个路径,所以对于5乘5的板,你有25 * 2 ^ 50~ = 10 ^ 16路径。
改进这一点的一种方法是交错遍历图表并检查字典,如果当前路径的单词不是字典单词的前缀则中止:
class Board {
char[][] ch;
boolean[][] visited;
Trie dictionary;
void find() {
StringBuilder prefix = new StringBuilder();
for (int x = 0; x < maxx; x++) {
for (int y = 0; y < maxy; y++) {
walk(x, y, prefix);
}
}
}
void walk(int x, int y, StringBuilder prefix) {
if (!visited[x][y]) {
visited[x][y] = true;
prefix.append(ch[x][y]);
if (dictionary.hasPrefix(prefix)) {
if (dictionary.contains(prefix)) {
System.out.println(prefix);
}
int firstX = Math.max(0, x - 1);
int lastX = Math.min(maxx, x + 1);
int firstY = Math.max(0, y - 1);
int lastY = Math.min(maxy, y + 1);
for (int ax = firstX; ax <= lastX; ax++) {
for (int ay = firstY; ay <= lastY; ay++) {
walk(ax, ay, prefix);
}
}
}
prefix.setLength(prefix.length() - 1);
visited[x][y] = false;
}
}
如您所见,方法walk调用自身。这种技术称为recursion。
这样就可以找到支持有效前缀查询的字典的数据结构。最好的数据结构是Trie。唉,JDK没有实现,但幸运的是,写一个并不难。
注意:此答案中的代码尚未经过测试。
答案 1 :(得分:0)
一种相当直接的概念化方法是对每个位置应用breadth-first search(BFS)方法(或深度优先,取决于您以后可能要进行哪些调整)。这将为您提供所有可能的字母组合,最多可达到等于搜索最大深度的字符级别。根据您的要求,例如允许的最长单词,最长运行时间,以及通过数据结构或文件提供字典,这可能是关键部分。
或者,您可能需要进行更多优化。如果是这样,请考虑如何加快BFS或DFS。如果你做了一个DFS但是知道三个字符,那么没有一个单词以“zzz”开头怎么办?你可以通过不必遍历所有可以想象的顺序来节省很多时间。要有效地查看单词,您可能需要进一步调整。但是我从Java的内置功能开始(在这个例子中会想到String.startsWith()),测量性能(可能是有限的最大字长),然后在需要的时间和地点进行优化。
答案 2 :(得分:0)
首先使用简单的重复方法将行,列和对角线转换为字符串。然后,我会把它变成一个StringBuilder,或者为了检查哪些单词是真实的,并消除那些不是直接来自StringBuilder的单词。然后,只需将其打印到String.There有很多有用的工具来消除或替换java中的单词。