F#中的集合交集

时间:2013-10-08 00:18:01

标签: syntax f# intersection

试图了解this question的答案之一。我编辑的代码看起来像这样,但它只返回[]

let rec intersect a b =
    let L1 = List.sort(a)
    let L2 = List.sort(b)
    match L1 with
    |h::t -> match L2 with
             |h2::t2 -> 
                 if h=h2 then h::(intersect t t2)
                 else if h>h2 then intersect t L2 else intersect L1 t2
             |[] -> []
    |[] -> [];;

intersect [1;2;3] [2;3;4]

我需要更改什么才能返回相交值的列表(设置)?

1 个答案:

答案 0 :(得分:1)

使用Set类型可以找到2个列表的交集。这基本上是一个不可变的HashSet。

let a = [1;2;3]
let b = [2;3;4]
let intersect a b = Set.intersect (set a) (set b) |> Set.toList

编辑:

Shredderroy是正确的,你的逻辑是在你的其他人之间交换的,如果&其他条件。另外作为F#递归的介绍,你不应该有像h::(intersect t t2)这样的返回,因为这不是正确的尾递归,如果列表足够长,可能会导致堆栈溢出。我能用正确的尾递归得到最接近原始代码的是:

let intersect a b =
    let rec loopy L1 L2 acc =
        match L1 with
        |h::t -> 
            match L2 with
            |h2::t2 -> 
                if h=h2 then 
                    loopy t t2 (h::acc)
                elif h>h2 then 
                    loopy L1 t2 acc
                else 
                    loopy t L2 acc
                 |[] -> List.rev acc
        |[] -> List.rev acc
    loopy (List.sort a) (List.sort b) []