在SML中检查列表的元素

时间:2013-12-03 01:38:22

标签: sml ml

您好我是ML / SML的新手,我正在尝试编写作为输入2列表的函数。一个列表包含4个随机字符串[“duck”,“goose”,“swan”,“gull”],第二个包含另外4个字符串[“duck”,“swan”,“goose”,“pigeon”]。

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

所以考虑到上面的两个例子,它会输出[“是”,“可能”,“可能”,“否”]。

这是我到目前为止所做的,但我无法弄清楚如何以递归方式调用main函数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;

非常感谢任何帮助。

1 个答案:

答案 0 :(得分: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"] *)