【问题标题】:Checking elements of a list in SML检查 SML 中列表的元素
【发布时间】:2013-12-18 22:12:42
【问题描述】:

您好,我对 ML/SML 比较陌生,我正在尝试编写将 2 个列表作为输入的函数。第一个列表包含 4 个随机字符串 ["duck","goose","swan","gull"],第二个列表包含另外 4 个字符串 ["duck","swan","goose","pigeon"]。

我想做的是检查第一个列表中的每个元素与另一个元素。如果字符串在相同的位置并且相等,则输出“是”。如果元素不在同一位置但在列表中,则输出'maybe',如果元素不在第二个列表中,则输出'no'。

因此,鉴于上面的 2 个示例,它将输出 ["yes","maybe","maybe","no"]。

这是我到目前为止所做的,但我不知道如何继续递归调用主函数 checkEqual 来迭代整个第一个列表。

 fun buildStringList nil nil = nil
|buildStringList lst appList = 
    lst @ appList   
in
fun checkEqual nil nil = nil
| checkEqual code guess =
    if hd code = hd guess then
        buildStringList ([])(["yes"])
    else if hd code = hd(tl guess) then
        buildStringList ([])(["maybe"])
    else if hd code = hd(tl(tl guess)) then
        buildStringList ([])(["maybe"])
    else if hd code = hd(tl(tl(tl guess))) then
        buildStringList ([])(["maybe"])
    else 
        buildStringList ([])(["no"])        
end;

任何帮助将不胜感激。

【问题讨论】:

    标签: sml ml


    【解决方案1】:

    有两个代码路径,按索引比较项目[“是”条件],然后在不考虑索引的情况下比较它们[“可能”路径]。使用递归和辅助函数 [或两个] 允许遵循两个代码路径:

    val ls1 = ["duck", "goose", "swan", "gull"]
    val ls2 = ["duck", "swan", "goose", "pigeon"]
    
    fun checker (list1,list2) =
        (* Zipping the two lists together  creates
           a list of pairs that can be searched
           for "yes" values as the first part of the aux function. 
           It might be worth checking to see if
           ListPair.zipEq is more suited to the
           needs of a particular appliation. *)        
        let val zipped =  ListPair.zip(list1, list2)
    
        (*  find_in_list is called if there is
            no "yes" match. It recurses down
            list2 with the string from list1
            which did not return "yes". *)
        fun find_in_list (x, xs) =
            case xs
             of [] => "no"
             | x'::xs' => 
               if x' = x
               then "maybe"
               else find_in_list (x, xs')
        (*  This function could be the main body
            of checker, but instead it trampolines.
            First it checks for "yes". Either appends
            "yes" onto a recursive call to itself or
            otherwise appends a call to find_in_list
            onto a recursive call to itself. 
            The type checker wants an explicit type
            for lop because the record is being accessed
            with #1 and #2 *)
        fun aux (lop : (string * string) list) =
            case lop
             of [] => []
             | x'::xs' =>
               if #1 (hd lop) = #2 (hd lop)
               then "yes"::aux (tl lop)
               else (find_in_list (#1 (hd lop), list2))::(aux (tl lop))
        in aux(zipped) end
    
    checker (ls1,ls2)  (* returns ["yes", "maybe", "maybe", "no"] *)
    

    【讨论】:

    • 没有理由在lop 上使用hdtl - 您已经将其拆分为x'xs',使用它们会更清晰。此外,除了使用#1 (hd lop)(或#1 x'),您也可以进行模式匹配:将x'::xs' 替换为(a, b)::xs'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多