2014-01-12 34 views
3

我剛開始學習SML中的函數式編程,我想知道如何將以下兩個函數組合到一個函數中。功能隔離使用幫助函數'removed'刪除任何類型('a)的列表的重複項。刪除SML中的列表中的重複項

fun isolate [] = [] 
    | isolate (l as x::xs) = x::isolate(remove(x,xs)) 

fun remove (x,[]) = [] 
    | remove (x,l as y::ys) = if x = y then remove(x,ys) else y::remove(x,ys) 

因此,爲了更好地理解SML中的構造,如何將隔離中的函數刪除?這可能看起來微不足道,但我已經考慮過了,無法弄清楚。感謝您的幫助!

回答

7

一種方法是在isolate內定義remove

fun isolate [] = [] 
    | isolate (l as x::xs) = 
     let fun remove (x,[]) = [] 
      | remove (x,l as y::ys) = if x = y 
             then remove(x,ys) 
             else y::remove(x,ys) 
     in 
     x::isolate(remove(x,xs)) 
     end 

或者,使重複數據刪除一個功能,雖然這一切確實是使用庫函數List.filterremove做同樣的事情。

fun isolate [] = [] 
    | isolate (x::xs) = x::isolate(List.filter (fn y => y <> x) xs) 
+0

這正是我一直在尋找!謝謝! – macalaca

+0

嘿@qaphla,當我編譯你的代碼我得到一個操作符和操作數不同意錯誤,我找不到錯誤。 – macalaca

+0

沒關係。我在let的'in'部分調用remove方法時發現它。你沒有通過正確的論點。 – macalaca

0

我想針對性地提出這個問題的以下解決方案:

fun remove_duplicates(xs: int list) = 
    let 
     fun check(xs: int list, item: int) = 
      if null xs 
      then false 
      else if hd xs = item 
      then true 
      else check (tl xs, item) 
     fun go_through_list(xs: int list) = 
      if null xs 
      then [] 
      else if check(tl xs, hd xs) 
       then go_through_list(tl xs) 
       else hd xs :: go_through_list(tl xs) 
    in 
     go_through_list(xs) 
    end 

它的代碼的行數比由@qaphla

0

我的想法propounded解決方案:定義一個嵌套函數檢查列表中是否有重複的元素:

fun set(nums:int list)= 
    let fun duplicate(x:int, l:int list)= 
    if null l 
    then false 
    else hd l=x orelse duplicate(x,tl l) 
    in 
     if null nums 
     then [] 
     else 
     let val s=set(tl nums) 
     in if duplicate(hd nums,s) 
     then s 
     else hd nums::s 
     end 
    end 

但它會給出一個列表t帽子只是每個重複元素的最後一個。

0

我的想法是,先對列表進行排序,然後遞歸返回一個新的列表,而重複:

fun remove_duplicates(l: int list) = 
if null(l) 
then [] 
else if null(tl l) 
then l 
else 
    let 
     fun compare(x: int, y: int) = x > y 
     fun sort(l: int list) = ListMergeSort.sort(compare) l 
     val l_sorted = sort(l) 
    in 
     if (hd l_sorted) = (hd (tl l_sorted)) 
     then remove_duplicates(tl l_sorted) 
     else (hd l_sorted)::remove_duplicates(tl l_sorted) 
    end