これを解決する1つの方法は次のとおりです。
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パス。
これを改善する1つの方法は、グラフのトラバースと辞書のチェックをインターリーブし、現在のパスの単語が辞書の単語のプレフィックスでない場合は中止することです。
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には実装が含まれていませんが、幸いなことに、実装を作成するのは難しくありません。
注:この回答のコードはテストされていません。