我需要编写一个函数来回答这些规范:
clean_list( [],s1] = NONE
clean_list( xs, "") = NONE
clean_list ([s1, s1, s1, s1], s1) = NONE
clean_list([s1, s2, s3, s2, s1], s3) = [s1, s2, s2, s1]
其中s1
,s2
,s3
是一些字符串,xs
是字符串列表。
我能够使用两个辅助函数is_into(xs: string list, s1: string) -> bool
和remove(xs: string list, s1: string) -> string list
来完成它,但在列表中两次递归似乎很难看。
clean_list(xs: string list, s1: string) =
case (xs, s1) of
( [], _ ) => NONE
|( _, "" ) => NONE
|( _, _) => if is_into(xs, s1)
then remove(xs, s1)
else NONE
有没有办法在列表中没有递归两次(is_into
一次,remove
一次)?
注意:不使用任何内置函数。
对不起,我忘记了规范
中的重要案例clean_list ([s1, s2, s3, s4], s10] = NONE
答案 0 :(得分:1)
您可以轻松地逐个浏览列表,逐个元素并删除与给定字符串匹配的所有内容,最后返回SOME lst
,其中lst
是结果列表
fun clean_list ([], _ ) = NONE
| clean_list (_, "") = NONE
| clean_list (xs, str) =
let
fun clean_list' [] = []
| clean_list' (x::xs) =
if x = str then
clean_list' xs
else
x :: clean_list' xs
in
SOME (clean_list' xs)
end
<强>更新强>
我注意到上面的代码实际上没有处理这种情况:clean_list ([s1, s1, s1, s1], s1) = NONE
。但是这很容易解决。
我可以看到,根据您的新更新规范,如果元素首先不在列表中,则应返回NONE
。这与说法相同,如果在浏览所有元素时没有删除任何元素,则返回NONE
。
希望您可以看到这可以通过向辅助函数添加一个额外的布尔参数来实现,最初将其设置为false,然后在每次递归调用中传递其值,除非在删除元素的情况下,在这里它总是可以设置为true。
然后,可以使用此选项确定天气以返回SOME lst
,其中lst
是结果列表,或NONE
如果没有删除任何元素。
鉴于这两件事需要修复,将辅助函数建立在累积参数中的结果可能是个好主意。通过这种方式,您可以完全控制,并且当累积列表最后为空时可以轻松返回NONE
。