如果您不需要所有可能的解决方案,而只需要一个掩码列表,该列表将匹配“接受列表”中的至少一个项目并且不匹配“忽略列表”中的任何项目,那么您很可能通过以下方式改进您当前的算法编写一个简单的O(n*m)
算法(其中n
和m
是列表长度)。
如果您的列表相对较短,这将比从 0 迭代到 2 29快得多。此外,如果这些列表永远不会改变并且您只需要这样做一次,那么这可能是您的最佳选择。
伪算法将类似于:
for each candidate in the "accept list"
do a bitwise AND with all items in the "ignore list"
if there is a match then (break as soon as you find a match)
this candidate cannot be matched
else
this candidate is one of the solutions
当然,这将返回只能匹配单个项目的掩码。如果您想要最小的掩码集,您可以对候选列表进行后处理并丢弃已包含在其他掩码中的掩码(即附加的O(n*n)
)。
如果您的“忽略列表”中有大量项目,并且需要经常查找列表,则将忽略的项目放入trie(或radix trie或DAWG,这些更多或更少相同的东西)。
对于每个候选者,您将一点一点地遍历特里树并快速丢弃在掩码1
中有位代替位的项目。0
这会产生类似O(n+m)
复杂性O(m)
的东西(构建 trie,O(1*n)
为接受列表中的每个项目查找 trie):
(presuming you have built a trie from "ignore list" items)
for each candidate in the "accept list"
get a binary representation of the candidate
perform a dfs of the trie
if node at level k is 1 and candidate bit at position k is 0
then
discard that subtree
else
continue searching until the last leaf
这一切都取决于您的列表的实际长度,以及您需要执行此搜索的频率。如果您有两个列表,每个列表包含 10000 个项目,并且您只需要执行一次,我会选择第一个算法,它可能需要不超过几秒钟的时间来完成(确切的运行时间将取决于忽略列表中的早期匹配项)。