检查单词是否可以快速输出给定的字母

时间:2013-02-10 03:11:50

标签: algorithm data-structures dictionary

我有一些字母和频数。我有很长的单词列表(1M说)。

假设我有A-1, B-1, D-1(“最多一个A,最多一个B,最多一个D”,那么我可以{{1} },但不是"BAD"

我可以在对数时间或类似的东西中知道哪些字可以用这些字母制作,而不是遍历所有单词并查看单词中每个字母的计数?

这些单词可以使用哪些数据结构?也许是特里?我不知道他们。如果我可以用它存储每个单词所需的字母也会很棒。请帮忙!

3 个答案:

答案 0 :(得分:3)

这是数据结构的(文字)草图。

             [root]
         ----- | -----
       A1      A2     B1 ...
  ----/-    ---|---    -\----
 B1 C1 [a]  B1 B2 C1  C1 C2 D2 ...

它是一棵树,其中叶节点是单词列表中的单词。叶节点上的单词完全由包含从根到该节点的路径组成的字母组成。非叶节点标有字母和计数。节点的子节点必须是叶子(单词)或者在字母表后面有严格的字母。因此,要进入“cat”,您沿着路径A1,C1,T1走,cat(和act)将成为T1的孩子。在每个节点,您遍历计数≤您的输入计数的子项(因此对于包A3, C1, T2,您将遍历标记为A1,A2,A3,C1,T1或T2的任何节点。

在最坏的情况下(每个字匹配),遍历花费O(n)时间,但平均花费少得多。对于小输入包,它只会遍历几个节点。对于一个大的输入包,它遍历许多节点,但它也会找到很多单词。

树中每个字母最多包含 一个节点,因此它的大小最多与字列表的长度成正比。

这是一个节省时间和空间的结构,可以相对容易地计算和存储 - 它不会占用比单词列表更多的空间,并且查询速度非常快。

答案 1 :(得分:1)

如果你需要那些所有字母的单词,我之前做过类似的事情(我的填字游戏作弊程序,我很惭愧地说)。

我拿了一个字典文件并对其进行了预处理,因此每行都对字母进行了排序,后跟单词本身,如:

aaadkrrv:aardvark

然后,如果您有字母ardvkraa,请对其进行排序,然后在冒号前查找包含该字符串的行。我使用grep,因为O(n)足够好但你可以轻松地将所有行放入平衡的二叉树中,以提供O(log n)复杂度。

如果您只使用某些字母的单词,那将无济于事,但不清楚这是否是您想要的。

答案 2 :(得分:0)

我不能说我能从你的描述中100%理解你提出的问题,但从我看到的,你可以做到以下几点:

您索引单词列表。例如,'B1'是一个索引,它将包含一个包含不超过一个字母B的条目列表,或者满足您要解决的问题的要求。您还可以使用“复合”索引,例如沿同一行的“A1B1”。考虑到您可以为索引编制的时间预算,您可以创建非常深的哈希值。如果你使用一个包含26个字母的字母表并想要散列4个字母的组合,那么它只有14,950个索引,而如果它是3个字母,那么它只有2,600个。可以在列表上的一次迭代期间构建索引,因此它们的创建是线性的。一旦超过此阶段,您的大部分查找将是对数的。在我的示例中,您的4个字母单词查找将是单个提取。当然,对于较长的字母组合,首先使用索引,然后迭代。