0

我有一个 Java 学校项目,我也被分配了。现在我遇到了项目的一部分问题,我无法弄清楚。应用程序必须从二维字符数组(char[][] 板)生成所有可能的单词组合(可以通过字典验证)。该板是动态的,因为用户可以选择比例:4x4、5x5、4x5、5x4、4x6,...所以我猜这里嵌套循环不合适,如果我错了,请纠正我。单词必须水平、垂直和对角生成。4x4 板的示例:

| 你| 一个 | 你| 小号 |

| n | n | 我 | 我 |

| 一个 | ○ | 电子| 乙 |

| 电子| 你| 电子| z |

    Code was completely wrong.

另一个想法可能是暴力破解板上所有可能的路径,然后尝试那些保存的路径来验证它是否是一个单词。

提前致谢!

4

3 回答 3

2

解决此问题的一种方法是:

for each path on the board
    if corresponding word in dictionary
        print it

要查找所有路径,您可以调整任何图遍历算法

现在这会很慢,因为有很多这样大小的电路板路径(对于具有 n 个单元的电路板,我们最多可以有n * 4 ^ (n - 1)路径,所以对于 5 x 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 方法会调用自身。这种技术称为递归

剩下的就是为字典找到支持有效前缀查询的数据结构的问题。最好的这种数据结构是Trie。唉,JDK 不包含实现,但幸运的是,编写一个实现并不难。

注意:此答案中的代码未经测试。

于 2013-01-20T22:22:00.477 回答
0

一种相当直接的概念化方法是将广度优先搜索(BFS) 方法应用于每个位置(或深度优先,取决于您以后可能想要进行的调整)。这将为您提供所有可能的字母组合,最高字符级别等于搜索的最大深度。根据您的要求,例如允许的最长单词、最长运行时间以及是否通过数据结构或文件提供字典,这可能是关键部分。

或者,您可能需要进行更多优化。如果是这样,请考虑如何加快 BFS 或 DFS。如果您进行了 DFS,但知道其中没有以“zzz”开头的三个字符怎么办?不必遍历所有可能的排序,您可以节省大量时间。为了有效地查找单词,您可能需要进行进一步的调整。但我会从 Java 的内置功能开始(在这种情况下会想到 String.startsWith()),测量性能(可能使用有限的最大字长),然后在需要的时间和地点进行优化。

于 2013-01-20T19:01:04.703 回答
0

首先使用简单的重复方法将行、列和对角线转换为字符串。然后,我会将它变成一个 StringBuilder,或者为了检查哪些单词是真实的并消除那些不是直接来自 StringBuilder 的单词。然后,只需将它打印到一个字符串。有很多有用的工具可以消除或替换 java 中的单词。

于 2015-03-10T12:02:31.453 回答