我在编写函数时遇到问题,结果如下所示:
split([7;1;4;3;6;8;2], 4) = ([1;3;2;4], [7;6;8])
我目前编写的代码:
let split(list, number)=
let split1(list, number, lesser, greater)=
if list = [] then lesser::greater
else if List.hd list <= element then (List.hd list)::(lesser)
else (List.hd list)::(greater)
in
(List.tl lista, element, [], []);;
提前感谢您的帮助。
答案 0 :(得分:1)
也许我对以下代码段的评论会有所帮助:
let split list num =
let rec loop lesser greater list =
match list with
| [] -> (lesser, greater)
(* when your initial list is empty, you have to return the accumulators *)
| x :: xs ->
if x <= num then
(* x is lesser than num, so add x in the lesser list and
call loop on the tail of the list (xs) *)
else
(* x is greater than num, so add x in the greater list and
call loop on the tail of the list (xs) *)
in
(* here you make the first call to loop by initializing
your accumulators with empty list*)
loop [] [] list
答案 1 :(得分:0)
对于未来,在SO上提问时更有针对性。你的问题究竟是什么?如果有人希望别人帮助他们,那么用户会持怀疑态度,但他们不会自助。
您的代码几乎具有正确的结构,但是有一些错误似乎正在妨碍您。
首先lesser::greater
是错误的,因为cons运算符的左侧必须是一个列表本身,但你真正想要的是一个列表,其中这两个都是元素。所以请尝试[lesser;greater]
。
其次,如果你仔细考虑你的代码,你会发现它突然停止了。您检查了第一个元素,但是您没有查看列表的其余部分。由于您希望继续拆分列表,因此您需要使用代码继续执行直到列表末尾。为此,我们使用递归。递归意味着您的函数split1
将再次调用自身。第一次看到它时可能会非常混乱 - 每次split1运行时,它将关闭第一个元素,然后拆分列表的其余部分。
(List.hd list)::(lesser)
实际上意味着什么?这里的较小部分实际上意味着列表其余部分中的所有较小元素 。你需要继续从列表中取出一个元素并将其放入更小或更大的位置。
最后避免过度使用List.hd - 使用模式匹配找到头部和尾部更为简洁。
这是代码的工作版本:
let split(list, number)=
let rec split1(list, number, lesser, greater)=
match list with
| [] -> [List.rev lesser;List.rev greater]
| head::tail ->
match (head <= number) with
true -> split1(tail,number,head::lesser,greater)
| false -> split1(tail,number,lesser,head::greater)
in split1(list, number, [], []);;
split([1;2;3;4;5],3);;
split1函数一次关闭一个元素,并将它们添加到列表中。