我正在尝试获取三个字符串列表,并让代码返回一个列出三个字符串的列表。如果列表的大小不相等,那么我们使用“ - ”表示缺少值。
例如:
interleave3 ["1"; "2"; "3"] ["4"] ["5"; "6"]
应该返回:
["1"; "4"; "5"; "2"; "-"; "6"; "3"; "-"; "-"]
答案 0 :(得分:2)
如果任务只是将元素交错,直到所有列表都为空,那么这将是相当简单的;只需旋转列表,同时一次附加一个元素,直到它们全部为空。
let rec interleave3 xs ys zs =
match xs, ys, zs with
| [], [], [] -> []
| [], ys, zs -> "-" :: interleave3 ys zs []
| x::xs, ys, zs -> x :: interleave3 ys zs xs
但是,由于要求是每个列表应该有效地填充到相同的长度,我们需要以某种方式跟踪最长列表的持续时间,并继续填充结果列表,直到填充了列表。这样做的一种方法是保持总计数,并在我们完成后继续进行,直到总数可被3整除,此时我们知道结果列表具有相同数量的元素:
let interleave3 xs ys zs =
let rec aux xs ys zs n =
match xs, ys, zs with
| [], [], [] when n mod 3 = 0 -> []
| [], [], [] -> "-" :: aux [] [] [] (n+1)
| [], ys, zs -> "-" :: aux ys zs [] (n+1)
| x::xs, ys, zs -> x :: aux ys zs xs (n+1)
in aux xs ys zs 0
答案 1 :(得分:1)
我建议尝试两个列表,然后你去3个或更多列表。一旦理解了两个模式,就可以为更多列表扩展相同的概念。我写了一个快速的解决方案,但我并不认为它是惯用的OCaml。 OCaml中的列表也以分号分隔。
let rec patternMatching xs ys zs =
match xs, ys, zs with
| [], [], [] -> []
| x::xs, [], [] -> x :: "-" :: "-" :: patternMatching xs [] []
| [], y::ys, [] -> "-" :: y :: "-" :: patternMatching [] ys []
| [], [], z::zs -> "-" :: "-" :: z :: patternMatching [] [] zs
| x::xs, y::ys, [] -> x :: y :: "-" :: patternMatching xs ys []
| x::xs, [], z::zs -> x :: "-" :: z :: patternMatching xs [] zs
| [], y::ys, z::zs -> "-" :: y :: z :: patternMatching [] ys zs
| x::xs, y::ys, z::zs -> x :: y :: z :: patternMatching xs ys zs
# patternMatching ["1"; "2"; "3"] ["4"] ["5"; "6"];;
- : string list = ["1"; "4"; "5"; "2"; "-"; "6"; "3"; "-"; "-"]