Algorithm 检查单词是否能快速地由给定的字母组成

Algorithm 检查单词是否能快速地由给定的字母组成,algorithm,data-structures,dictionary,Algorithm,Data Structures,Dictionary,我有一些字母和频率计数。我有一个很长的单词列表(100万个单词) 假设我有A-1,B-1,D-1(“最多一个A,最多一个B,最多一个D),那么我可以使变为“坏”,但不能使变为“RAD” 我能知道哪些单词可以在对数时间内由这些字母组成,而不是遍历所有单词并查看单词中每个字母的计数吗 这些单词可以使用什么数据结构?也许来一杯茶?我不知道他们。如果我能用它存储每个单词所需的字母,那也太好了。请帮忙 如果你需要包含所有字母的单词,我以前也做过类似的事情(我的纵横填字游戏作弊程序,我很不好意思这么说) 我

我有一些字母和频率计数。我有一个很长的单词列表(100万个单词)

假设我有
A-1,B-1,D-1
(“最多一个
A
,最多一个
B
,最多一个
D
),那么我可以使
变为“坏”
,但不能使
变为“RAD”

我能知道哪些单词可以在对数时间内由这些字母组成,而不是遍历所有单词并查看单词中每个字母的计数吗


这些单词可以使用什么数据结构?也许来一杯茶?我不知道他们。如果我能用它存储每个单词所需的字母,那也太好了。请帮忙

如果你需要包含所有字母的单词,我以前也做过类似的事情(我的纵横填字游戏作弊程序,我很不好意思这么说)

我获取了一个字典文件并对其进行了预处理,这样每一行都会对字母进行排序,然后是单词本身,如:

aaadkrrv:aardvark
然后,如果您有字母
ardvkraa
,请对其排序,然后在冒号之前查找包含该字符串的行。我使用了
grep
,因为O(n)已经足够好了,但是你可以很容易地把所有的行放到一个平衡的二叉树中,给你O(logn)的复杂性


如果你想要的是只使用部分字母的单词,那没有多大帮助,但不清楚这是否是你想要的。

如果你需要包含所有字母的单词,我以前也做过类似的事情(我的纵横填字游戏,我很惭愧地说)

我获取了一个字典文件并对其进行了预处理,这样每一行都会对字母进行排序,然后是单词本身,如:

aaadkrrv:aardvark
然后,如果您有字母
ardvkraa
,请对其排序,然后在冒号之前查找包含该字符串的行。我使用了
grep
,因为O(n)已经足够好了,但是你可以很容易地把所有的行放到一个平衡的二叉树中,给你O(logn)的复杂性

如果你在寻找只使用部分字母的单词,那么这不会有多大帮助,但不清楚这是否是你想要的。

下面是数据结构的(文字)草图

             [root]
         ----- | -----
       A1      A2     B1 ...
  ----/-    ---|---    -\----
 B1 C1 [a]  B1 B2 C1  C1 C2 D2 ...
这是一棵树,其中叶节点是单词列表中的单词。叶节点上的单词完全由从根节点到该节点的路径组成的字母包组成。非叶节点用字母和计数标记。节点的子节点必须是叶(单词)或字母表中的字母。因此,要进入“cat”,你要沿着路径
A1、C1、T1
,而
cat
(和
act
)将是T1的孩子。在每个节点上,遍历具有count的子节点≤ 您的输入计数(因此对于行李
A3、C1、T2
,您将遍历标记为A1、A2、A3、C1、T1或T2的任何节点)

在最坏的情况下(每个单词都匹配),遍历需要O(n)个时间,但平均而言所需时间要少得多。对于一个小的输入包,它将只遍历几个节点。对于大型输入包,它会遍历许多节点,但也会找到许多单词

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

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

下面是数据结构的(文字)示意图

             [root]
         ----- | -----
       A1      A2     B1 ...
  ----/-    ---|---    -\----
 B1 C1 [a]  B1 B2 C1  C1 C2 D2 ...
这是一棵树,其中叶节点是单词列表中的单词。叶节点上的单词完全由从根节点到该节点的路径组成的字母包组成。非叶节点用字母和计数标记。节点的子节点必须是叶(单词)或字母表中的字母。因此,要进入“cat”,你要沿着路径
A1、C1、T1
,而
cat
(和
act
)将是T1的孩子。在每个节点上,遍历具有count的子节点≤ 您的输入计数(因此对于行李
A3、C1、T2
,您将遍历标记为A1、A2、A3、C1、T1或T2的任何节点)

在最坏的情况下(每个单词都匹配),遍历需要O(n)个时间,但平均而言所需时间要少得多。对于一个小的输入包,它将只遍历几个节点。对于大型输入包,它会遍历许多节点,但也会找到许多单词

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


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

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


你为你的单词列表编制索引。例如,“B1”是一个索引,它将包含一个包含不超过一个字母B的条目列表,或者满足您正在解决的问题的要求。你也可以有“综合”指数,像“A1B1”沿着相同的线。考虑到索引的时间预算,您可以创建相当深的哈希。如果你使用的是26个字母的字母表,并且想要散列4个字母的组合,那么它只有14950个索引,如果是3个字母,那么它只有2600个索引。索引可以在列表的一次迭代中建立,因此它们的创建是线性的。一旦过了这个阶段,大部分的查找都是对数的。在我的示例中,您的4个字母单词查找将是一次获取。当然,对于较长的字母组合,您可以先使用索引,然后进行迭代。

我不能说我可以100%地从您的描述中理解您提出的问题,但从我看到的情况来看,您可以执行以下操作:

你为你的单词列表编制索引。例如,“B1”是一个索引,它将包含一个包含不超过一个字母B的条目列表,或者满足问题a的要求