【问题标题】:List matching in OCamlOCaml 中的列表匹配
【发布时间】:2019-02-16 13:06:51
【问题描述】:

我有一个正在 Ocaml 中工作的函数。它由一个函数组成,该函数接受两个字符串列表并返回一个字符串列表。该功能的操作如下。它扫描第一个列表中的每个单独的字符串,如果在第二个列表中找到相应的匹配项,则返回该匹配项。如果第二个列表有重复匹配,则匹配将返回两次。以下是我编写的描述预期行为的测试用例:

let test () : bool =
  (in_both [] ["Pearl"; "Steven"]) = []
;; run_test "in_both empty name list 1" test

let test () : bool =
  (in_both ["Pearl"; "Steven"] []) = []
;; run_test "in_both empty name list 2" test

let test () : bool =
  (in_both ["Pearl"; "Amethyst"; "Henry"] ["Pearl"; "Steven"]) = ["Pearl"]
;; run_test "in_both one repeat in both lists" test

let test () : bool =
  (in_both ["Pearl"; "Amethyst"; "Gary"; "Blair"] ["Pearl"; "Amethyst"; "Blair"]) 
  = ["Pearl";"Amethyst";"Blair"]
;; run_test "in_both three different repeats in both lists" test

let test () : bool =
  (in_both ["Garnet"; "Amethyst"; "Pearl"] ["Pearl"; "Pearl"]) 
  = ["Pearl";"Pearl"]
;; run_test "in_both two repeat in second list" test

这是我的函数实现:

let rec in_both (names1: string list) (names2: string list) : string list =
  begin match (names1, names2) with
  |([],[])-> []
  |([],hd2::tl2)-> []
  |(hd1::tl1,[])-> []
  |(hd1::tl1,hd2::tl2)->if contains_str names2 hd1 = true then hd1::in_both tl1 
  tl2 else in_both tl1 names2
  end

我所有的测试都通过了,除了最后一个测试,看起来"Pearl" 没有在应该打印的时候打印两次。在我的实施中我可能做错了什么?作为参考,这里是我在 in_both 中调用的 contains_str 函数的函数定义:

let rec contains_str (l: string list) (name: string) : bool =
  begin match l with
  |[]-> false
  |hd::tl-> hd = name || contains_str tl name
  end

感谢任何帮助!

【问题讨论】:

  • in_both ["Pearl"; "Pearl"] ["Garnet"; "Amethyst"; "Pearl"] 怎么样?或者换句话说是in_both a b == in_both b a

标签: list recursion ocaml


【解决方案1】:

一种看待它的方式是contains_str 太弱了,无法做你想做的事。您想知道字符串出现多少次,而不仅仅是它是否出现。您可能会考虑一个函数,它返回字符串列表a 在字符串列表b 中出现的列表(如果没有出现则为空)。

此外,还有另一种情况,您当前的代码似乎无法正确处理:

# in_both ["a"; "b"] ["b"; "a"];;
- : string list = ["a"]

在我看来,没有理由仅仅因为在其中找到了hd1 而移到第二个列表 (tl2) 的末尾。可能第二个列表的头部出现在第一个列表的后面。

【讨论】:

  • 我必须多考虑一下contains_str 函数。至于小bug,我修改了then语句为then hd1::in_both tl1 (hd2::tl2),应该会更好,但是最后一次测试还是失败了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 2018-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多