2014-10-30 127 views
2

我正在處理一個程序,它將一個'+'或' - '附加到列表的某個元素上,具體取決於該元素的索引是奇數還是偶數(即交替總和清單)。SML - 獲取列表索引

但是,我很難識別每個元素的索引是什麼。我有代碼,我認爲應該追加正確的符號,使用if statementsmod

fun alternating([]) = 0 
    | alternating(l) = 
     if List.nth(l,hd(l)) mod 2 == 0 then '+'@hd(l)@alternating(tl(l)) 
     else '-'@hd(l)@alternating(tl(l)) 

然而,List.nth(l,hd(l))總是返回第二個索引,而不是第一處的元素。

+0

輸入和預期輸出的示例將會有所幫助。輸入是字符串列表嗎? – 2014-10-30 20:49:48

回答

2

在關閉的機會,你真的只是想否定整數他們,你可以通過他們進行某種總結,如果它很奇怪,我只會否定論證。使用相互遞歸一個能做到這一點,沒有任何明確的指標簿記:

fun alternate l = 
    let 
     fun alternate1 []  = [] 
     | alternate1 (x::xs) = (~x) :: alternate2 xs 
     and alternate2 []  = [] 
     | alternate2 (x::xs) = x :: alternate1 xs 
    in 
     alternate1 l 
    end 

它的工作原理就像這樣:

- alternate [1,2,3,4]; 
val it = [~1,2,~3,4] : int list 

我會強烈建議您使用模式匹配,而不是hd

編輯討論hd

作爲一個經驗法則,如果你需要hd你可能需要tl爲好。 hd是部分功能 - 如果列表爲空,它將拋出Empty。如果模式匹配,您可以方便地獲取列表頭部和尾部的變量,並且您可以看到需要處理空列表的視覺提醒。這是更美觀,IMO,看到:

fun foo []  = ... 
    | foo (x::xs) = ... 

比同等

fun foo l = 
    if null l 
    then ... 
    else (hd l) ... (tl l) 

換句話說,你會得到更短,更乾淨的代碼具有自動提醒,使其正確的。贏/贏。據我所知,以其他方式做這件事沒有什麼重大的優勢。當然,您可能會發現自己處於一種情況,即您知道列表中至少有一個元素,而您不需要執行其他任何操作。你仍然必須考慮給你的情況,但這是一個很好的經驗法則。

+0

使用'hd'代替什麼錯誤? – Delfino 2014-10-30 22:17:16

+0

@Delfini我在回答中已經擴展了這一點。 – 2014-10-30 22:26:02

+0

我會同意'x :: xs'更好看:) – Delfino 2014-10-30 22:31:59

1

如果你想用一個指數來裝飾你的列表,你可以嘗試像下面

fun add_index l = 
    let 
    fun add_index_helper (nil, _) = nil 
     | add_index_helper (h::tl,i) = (h,i) :: add_index_helper (tl,1+i) 
    in 
    add_index_helper (l,0) 
    end 

val x = add_index [0,1,4,9,16,25] 

,但你也可以直接計算奇偶校驗用同樣的方法

fun add_sign l = 
    let 
    fun add_sign_helper (nil, _) = nil 
     | add_sign_helper (h::tl,i) = (h,i) :: add_sign_helper (tl,1-i) 
    in 
    add_sign_helper (l,0) 
    end 

val y = add_sign [0,1,4,9,16,25] 

那麼你可以將奇偶校驗映射到字符串

fun sign_to_char (x,0) = (x,"+") 
    | sign_to_char (x,_) = (x,"-") 

val z = List.map sign_to_char y 

或者您可以直接添加符號

fun add_char l = 
    let 
    fun add_char_helper (nil, _) = nil 
     | add_char_helper (h::tl,0) = (h,"+") :: add_char_helper (tl,1) 
     | add_char_helper (h::tl,_) = (h,"-") :: add_char_helper (tl,0) 
    in 
    add_char_helper (l,0) 
    end 

val zz = add_char [0,1,4,9,16,25] 

或者,如果你有一個字符串列表,你想添加字符,你可以嘗試這樣的事情

fun signs L = 
    let 
    datatype parity = even | odd 
    fun signs_helper (nil ,_) = nil 
     | signs_helper (x::xs,even) = ("+"^x) :: signs_helper(xs,odd) 
     | signs_helper (x::xs,odd) = ("-"^x) :: signs_helper(xs,even) 
    in 
    signs_helper (L,even) 
    end 

val z = signs ["x","2y","3z","4"] 
(* this gives you val z = ["+x","-2y","+3z","-4"] : string list *)