使用哈希表进行单词搜索的算法是什么?

时间:2013-10-22 08:51:53

标签: c++ algorithm hash hashtable

这是一项任务。

我有一个哈希表(链表的数组),其中包含一串英语词典中的单词。

我还有一个高达100 x 100的二维数组字母,但我现在只显示3x3:

[a][b][c]
[g][a][c]
[b][t][a]

与任何单词搜索一样,单词可以水平,垂直,对角和向后排列。

我这里只展示了一个小网格,但如果我有一个更大的网格,那么也会有更大的字数。

我如何找到数组中的单词?看起来我在这里只需要“蝙蝠”和“出租车”。想象一下,我们有一个更大的网格,单词可以达到20个字母。这就是我能想到的:

  1. 从网格上的某个地方开始
  2. 检查2个字母的单词
  3. 检查所有8个方向
  4. 将您在哈希表中找到的任何内容扔出去检查匹配
  5. 重复步骤2,除了3,4,5,6,7,8,9,10个字母
  6. 返回步骤1,移到网格上的某个位置并重复
  7. 看起来似乎是一种非常愚蠢的做法。

1 个答案:

答案 0 :(得分:1)

散列的表

最简单(虽然不是特别有效)的方法是简单的递归。

对于每个单元格,递归地环顾四周,跟踪当前单词,并在每一步检查当前单词是否包含在哈希表中。

set up hash table with all words

for each cell c
  findWords(c, c.value)

findWords(cell c, string current)
  if current.length > longestWord
    return
  if hashTable.contains(current)
    output current
  for each neighbour n of c
    findWords(n, current + c.value)

现在,为了提高效率,我们基本上可以模拟trie

我们会将每个单词的所有前缀都放入哈希表中,因此对于"johnny",您需要"j""jo""joh",{{1哈希表中有},"john""johnn"

我们可以在哈希表中有一个标志来指示给定条目是否是有效字。因此,对于上述情况,只有"johnny"会有此标记。

"johnny"

Trie树

trie似乎是解决此问题的更好数据结构。

首先,用所有单词构造trie。然后,对于网格上的每个位置,检查根的值是否存在边缘。如果存在,则递归检查它的每个邻居,检查该值是否有边缘,并检查它的邻居,依此类推。

伪代码是这样的:

set up hash table with all words, but also all prefixes of words

for each cell c
  findWords(c, c.value)

findWords(cell c, string current)
  if hashTable.contains(current)
    if isValidWord(current)
      output current
    for each neighbour n of c
      findWords(n, current + c.value)