2016-09-01 3 views
1

Мне нужно сделать функцию, которая дает натуральное число n, вычисляет произведение чисел ниже n, которые не делятся на 2 или на 3 im запутаны в том, как использовать вложенные функции для того, чтобы решить эту проблему (также новое SML), вот мой код до сих порИспользование вложенных функций для поиска произведения чисел

fun countdown(x : int) = 
    if x=0 
    then [] 
    else x :: countdown(x-1) 

fun check(countdown : int list) = 
    if null countdown 
    then 0 
    else 

ответ

2

это не ясно из самого вопроса (часть упражнения в каком-нибудь классе?), как мы должны использовать вложенную поскольку существуют способы записи функции без вложенности, например,

fun p1 n = 
    if n = 1 then 1 else 
    let val m = n - 1 
    in (if m mod 2 = 0 orelse m mod 3 = 0 then 1 else m) * p1 m 
    end 

и есть также много способов, чтобы написать его с вложенными функциями, как

fun p2 n = 
    if n = 1 then 1 else 
    let val m = n - 1 
     fun check m = (m mod 2 = 0 orelse m mod 3 = 0) 
    in (if check m then 1 else m) * p2 m 
    end 

или

fun p3 n = 
    let fun check m = (m mod 2 = 0 orelse m mod 3 = 0) 
     fun loop m = 
      if m = n then 1 else 
      (if check m then 1 else m) * loop (m + 1) 
    in loop 1 
    end 

или как предыдущий ответ по @coder, только чтобы дать несколько примеров. Из них p3 несколько отличается тем, что внутренняя функция loop имеет «свободную переменную» n, которая относится к параметру внешнего p3.

2

Использование стандартной библиотеки, функция, которая производит номера [1; п -1],

fun below n = List.tabulate (n-1, fn i => i+1); 

функцию, которая удаляет число делится на 2 или 3,

val filter23 = List.filter (fn i => i mod 2 <> 0 andalso i mod 3 <> 0) 

функция, которая вычисляет произведение его вход,

val product = List.foldl op* 1 

и приклеивая их все вместе,

val f = product o filter23 o below 

Это генерирует список, фильтрует его и сворачивает его. Это отнимает больше памяти, чем необходимо. Было бы более эффективно делать то, что @FPstudent и @coder делать и генерировать числа, и немедленно либо сделать их частью конечного продукта, либо выбросить их, если они делятся на 2 или 3. Две вещи, которые вы могли бы сделать в Кроме того,

  1. Сделать функцию хвостовой рекурсивной, поэтому она использует меньше пространства стека.

  2. Обозначим итерацию/складывание в общий узор.

Например,

fun folditer f e i j = 
    if i < j 
    then folditer f (f (i, e)) (i+1) j 
    else e 

fun accept i = i mod 2 <> 0 andalso i mod 3 <> 0 
val f = folditer (fn (i, acc) => if accept i then i*acc else acc) 1 1 

Это похоже на Python's xrange.