2014-10-30 2 views
2

Я работаю над программой, которая добавляет «+» или «-» к элементу списка, в зависимости от того, является ли индекс этого элемента нечетным или четным (т.е. список сумм).SML - Получить индексы списка

Однако у меня возникли проблемы с определением индекса каждого элемента. У меня есть код, который я считаю, должен добавить правильный символ, используя if statements и mod

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

Примером ввода и ожидаемого выхода было бы полезно. Вводится ли список строк? –

ответ

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) 

Другими словами, вы получаете более короткий, чистый код с автоматическим напоминанием, чтобы сделать это правильно. Win/выигрыш. Насколько мне известно, нет никакого существенного преимущества для этого. Конечно, вы можете оказаться в ситуации, когда знаете, что в списке будет хотя бы один элемент, и вам не нужно ничего делать. Вы все еще должны учитывать случаи, которые вам даны, но это хорошее эмпирическое правило.

+0

Неправильно использовать 'hd' вместо этого? – Delfino

+0

@ Delfini Я расширил это в ответ. –

+0

Я соглашусь, что 'x :: xs' гораздо приятнее смотреть :) – Delfino

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 *) 
Смежные вопросы