【问题标题】:How to clean a list for a specific string and return the cleaned list or NONE如何清理特定字符串的列表并返回清理后的列表或 NONE
【发布时间】:2013-01-24 08:04:09
【问题描述】:

我需要编写一个函数来回答这些规范:

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]

其中s1s2s3 是一些字符串,xs 是字符串列表。

我可以使用两个辅助函数 is_into(xs: string list, s1: string) -> boolremove(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

【问题讨论】:

    标签: functional-programming sml smlnj


    【解决方案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

    【讨论】:

    • 我忘记了 clean_list ([s1, s2, s3, s4], s10] = NONE 规范中的一个重要案例
    • @sonia,您应该能够轻松扩展提供的解决方案来处理此问题。顺便说一句,我发现这个 (clean_list ([s1, s1, s1, s1], s1) = NONE) 案例也没有正确处理。如果没有,那么您应该改写/编辑您的问题以反映您遇到的问题。
    【解决方案2】:

    您的 clean_list 函数不会进行类型检查,因为某些分支的类型为 'a option,而其他分支的类型为 'b list

    假设您想返回'b list,则NONE 应替换为[]。您可以在 clean_list 上递归地使用模式匹配来避免需要辅助函数:

    fun clean_list(xs: string list, s1: string) =
        case (xs, s1) of
          ([], _) => []
        | (_, "") => []
        | (x::xs', _) => if x = s1 
                         then clean_list(xs', s1)
                         else x::clean_list(xs', s1)
    

    【讨论】:

    • 抱歉,我忘记了 clean_list ([s1, s2, s3, s4], s10] = NONE 规范中的一个重要案例
    猜你喜欢
    • 2020-03-03
    • 2023-01-06
    • 2015-08-18
    • 2023-04-03
    • 2021-02-05
    • 1970-01-01
    • 2014-07-17
    • 2011-09-21
    • 2018-12-04
    相关资源
    最近更新 更多