我有一个正在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
感谢您的帮助!
答案 0 :(得分:0)
一种查看方式是contains_str
太弱了,无法执行您想要的操作。您想知道字符串出现的次数多少次,而不仅仅是字符串是否出现。您可能考虑使用一个函数,该函数返回字符串列表a
中的字符串b
的出现列表(如果没有出现,则为空)。
此外,还有另一种情况,您当前的代码似乎无法正确处理:
# in_both ["a"; "b"] ["b"; "a"];;
- : string list = ["a"]
在我看来,没有理由仅因为在其中找到了tl2
而跳到第二个列表(hd1
)的末尾。可能第二个列表的标题出现在第一个列表的后面。