算法 - 查找满足输入元素任意组合的所有集合

时间:2017-08-08 00:05:55

标签: algorithm set

假设我们有一个输入,它是一个元素列表:

{a,b,c,d,e,f}

还有不同的集合可能包含这些元素的任意组合,也可能包含不在输入列表中的其他元素:

答:{e,f} B:{d,f,a} C:{g,a,b} D:{a,h,k}

算法应仅返回集A和B.

乍一看,我想到了对输入列表进行排序并循环遍历所有集合,检查集合中的每个元素是否都存在于输入列表中。在我的情况下,尽管输入列表很小但是集合的数量会很大,所以除了一次之外我不想遍历所有集合。输入通常会改变,但不会改变。

1 个答案:

答案 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")