假设我们有一个输入,它是一个元素列表:
{a,b,c,d,e,f}
还有不同的集合可能包含这些元素的任意组合,也可能包含不在输入列表中的其他元素:
答:{e,f} B:{d,f,a} C:{g,a,b} D:{a,h,k}
算法应仅返回集A和B.
乍一看,我想到了对输入列表进行排序并循环遍历所有集合,检查集合中的每个元素是否都存在于输入列表中。在我的情况下,尽管输入列表很小但是集合的数量会很大,所以除了一次之外我不想遍历所有集合。输入通常会改变,但不会改变。
答案 0 :(得分:1)
您可以将输入集的(有限!)字母转换为位集,然后使用二进制运算来测试另一个集是否是参考集的(完整)子集。
这是一个示例实现:
type CharSet = string
type EncodedCharSet = uint32
let encode (set : CharSet) : EncodedCharSet =
set.ToCharArray()
|> Array.fold (fun a c -> a ||| (1u <<< (int c - int 'a')) ) 0u
let inSet (reference : EncodedCharSet) (test : EncodedCharSet) : bool =
0u = (reference &&& test) ^^^ test
let test a b =
let (ae,be) = (encode a, encode b)
inSet ae be
[
"ef"
"dfa"
"gab"
"ahk"
]
|> List.map (test "abcdef")