递归地比较OCaml中列表中的元素

时间:2015-05-01 13:16:10

标签: list recursion ocaml

我的任务是创建一个m字portmanteaus列表,其中n字母重叠来自给定的单词列表。

例如,2字2字母重叠portmanteau将是:" collegenetics"由"大学"和"遗传学"。 3字2字母重叠可以是" firegaluminum"由" fire"," regal"和"铝"。

我用这种语法写了一个函数singleport:

let singleport word1 word2 n = 
match suffix word1 n = prefix word2 n with
| false -> "No Port" 
| true -> word1 ^ (prefixless word2 n)

确定两个单词是否可以是portmanteaus。但是,为了比较列表中的两个元素,我正在努力确定一种递归运行方式的方法,同时构建一个记录所有可能的portmantaus的新列表。

我认为可以使用List.fold_left因为使用累加器,但我不知道如何实现它,我将非常感谢任何建议。非常感谢你!

1 个答案:

答案 0 :(得分:1)

攻击任务的一种方法是将其拆分为可理解的小子任务,然后尝试合并它们。这是演绎法。

演绎

将演绎方法应用于您的任务,我们可以通过以下方式将其拆分:

  1. 创建连续对的列表
  2. 映射portmanteaus的列表
  3. 加入结果
  4. 要创建对列表,您需要编写以下函数:

    (** give a list, produces a list of consecutive pairs. 
        Fails with invalid argument, if list has odd length. *)
    val pair_list : 'a list -> ('a * 'a) list
    

    使用此功能,您可以使用map,将每个对转换为portmanteau列表,将一对映射到空列表,如果不可能的话。例如,鉴于此功能:

    val portmanteau : (string * string) -> string list
    

    现在我们可以使用List.concat加入所有内容:

    let portmanteau_of_list xs = 
      List.map portmanteau (pair_list xs) |> List.concat
    

    电感

    另一种方法是从其他方向移动,即不是从顶部向下移动,而是从底部移动。因此,有关此任务的归纳推理如下:

    1. 空列表的portmanteaus是一个空列表,
    2. 一个元素列表的portmanteaus是错误
    3. 当前两个元素不构成portmanteau时,大于2的列表的portmanteaus是列表中其余元素的portmanteaus
    4. 当前两个元素组成portmanteau时,列表大于2的portmanteaus是这两个元素的portmanteau以及列表中其余元素的portmanteaus。
    5. OCaml中的相同内容(未经测试):

       let rec portmanteau_of_list = 
       | [] -> []
       | [_] -> failwith "odd list"
       | x :: y :: xs -> match portmanteau x y with
         | None -> portmanteau_of_list xs
         | Some p -> p :: portmanteau_of_list xs