重写msort,因此它在F#中使用模式匹配

萨格

下面的代码是f#中mergesort的代码,我必须重写它,因此它使用模式匹配。

let rec msort xs =
let sz = List.length xs
        if sz < 2 then xs
        else let n = sz / 2
            let ys = xs.[0..n-1]
            let zs = xs.[n..sz-1]
            in merge (msort ys) (msort zs)

到目前为止,我已经到了这里:

let rec msort (vs: int list) =
    let sz = List.length xs
    match xs with 
    | List.length < 2 -> vs 
    | _ -> 
        let n = sz / 2
        let ys = xs.[0..n-1]
        let zs = xs.[n..sz-1]
        in merge (msort ys) (msort zs)

我似乎无法找出更好的方法。有谁可以帮助我吗?

亚伦·艾什巴赫

我可能会这样:

let rec msort (values: int list) =
    let n = values.Length / 2
    if n = 0 
    then values
    else let rec merge (xs: int list) (ys: int list) =
             match (xs, ys) with
             | ([], ys) -> ys
             | (xs, []) -> xs
             | (x :: xs1, y :: ys1) ->
                  if x < y
                  then x :: merge xs1 ys
                  else y :: merge xs ys1        

         let (first, second) = values |> List.splitAt n
         merge (msort first) (msort second)

模式匹配在初始逻辑(列表的长度,长度为0和1的早期退出)上并不是很有用,但是我认为在拆分后匹配子列表的大小写时,它使可读性更高。即使这样,在该msort部分中只有一个if / then,如果您确实想要:

let rec msort (values: int list) =
    match values.Length / 2 with
    | 0 -> values
    | n -> 
        let rec merge (xs: int list) (ys: int list) =
            match (xs, ys) with
            | ([], ys) -> ys
            | (xs, []) -> xs
            | (x :: xs1, y :: ys1) ->
                if x < y
                then x :: merge xs1 ys
                else y :: merge xs ys1        

        let (first, second) = values |> List.splitAt n
        merge (msort first) (msort second)

这仅将if/thenforx<y留在merge实现中,而我不会更改。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章