【问题标题】:Merge Two Lists in F# Recursively [duplicate]递归合并F#中的两个列表[重复]
【发布时间】:2016-09-28 22:00:20
【问题描述】:

我正在寻找一个递归函数来合并到 F# 中的整数列表

我从这个开始,但不知道下一步该做什么。

let rec merge xs ys =
    match xs with
    | [] -> ys
    | 

let li = [1;3;5;7;]
let ll = [2;4;5;8;]

【问题讨论】:

  • “合并”是什么意思?您是否尝试从每个列表中替换项目?还是它们总是从一开始就排序,并且您希望输出也被排序?
  • @kvb 我希望对合并列表进行排序。 1,2,3,4,5,5,7,8
  • 作为提示,如果同时对xsys 进行模式匹配(使用match xs, ys with ...),可能会更容易。

标签: f# recursion


【解决方案1】:

正如我在评论中所说,如果同时在 xs 和 ys 上进行模式匹配,这可能是最简单的:

let rec merge xs ys = 
  match xs,ys with
  | [],l | l,[] -> l
  | x::xs', y::ys' -> 
     if x < y then x :: (merge xs' ys) //'
     else y :: (merge xs ys')          //'

【讨论】:

  • 不错的代码。这假设输入是按开头排序的。
  • 这可以通过创建一个子函数并将新集合传递给该函数调用来轻松地变成尾递归。
  • 尝试使用它,例如 [1; 9]和[2; 9] 它将返回 [1; 2; 9; 9]。你应该用'else merge xs ys'来处理这个子句,一切都会好起来的
【解决方案2】:

我找到了一种可能适合提问者想要的方法。我不得不解决同样的问题,并且几乎没有上一周的 F# 课程,所以课堂上没有讨论整个语法,当我看到上面使用多重匹配(match lst1, list2 with ...)的答案时,我认识到它可以立即使用,但教授不允许使用,因此我不得不想出另一种选择。甚至认为它与使用更基本代码的算法基本相同。只是觉得我应该发布它=)

let rec merge2 list1 list2 = 
    let head list = match list with | [] -> 0 | h::t -> h
    let tail list = match list with | [] -> [] | h::t -> t
    match list1 with
    | [] -> []
    | h::t -> 
        //list2's head is 0 then list is empty then return whats in the first list 
        //(i.e no more values of second list to compare)
        if head list2 = 0 then list1
        elif h < head list2 then h :: merge2 t list2 
        else head list2 :: merge2 list1 (tail list2)

【讨论】:

    【解决方案3】:

    您已经拥有正确的基本情况之一:如果 xs 为空,则返回 ys。

    同样,如果 ys 为空,则返回 xs。

    对于xs和ys都不为空的情况,需要查看xs和ys的第一个元素(暂且称它们为x和y):

    如果 x 小于 y,那么它需要在最终列表中插入到 y 之前。所以你把y加到xs尾部与ys(包括y)合并的结果前面。

    否则 y 需要先出现。所以把y加到xs(包括x)和ys的尾部合并的结果前。

    【讨论】:

      【解决方案4】:

      它不是递归的,但是如果输入没有排序:

      let merge xs ys = (Seq.append xs ys) |> Seq.sort |> Seq.toList
      

      【讨论】:

        【解决方案5】:

        我会使用 List.fold 来做到这一点:

        let merge a b =
            List.fold (fun acc x ->
                if List.exists ((=)x) acc = false then
                    elem :: acc
                else
                    acc
            ) (List.sort a) b
        

        不过,这可能不是最快的方法。

        【讨论】:

          【解决方案6】:

          我不认为这是一个递归问题

          let a = [1;3;5]
          let b = [2;4;6]
          
          let c = Seq.append a b |> Seq.sort
          

          fsi 会话的输出: c:

          val it : seq<int> = seq [1; 2; 3; 4; ...]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-08
            • 2018-01-04
            • 2013-10-10
            • 1970-01-01
            • 1970-01-01
            • 2015-11-29
            相关资源
            最近更新 更多