удаление элемента из списка с помощью рекурсии и сопоставления с образцом - PullRequest
0 голосов
/ 07 сентября 2018

Используя рекурсию в F #, я должен написать рекурсивную функцию для удаления целого числа n из списка l. Функция принимает int и iList и возвращает iList (список целых чисел)

вот что у меня есть:

let rec remove n l match l with | E -> failwith "Empty List" | L(h,E) -> if (h=n) then 0 else h | L(h,t) -> if (h=n) then remove n t else h + remove n t

В приведенном выше коде я настроил его так, чтобы он возвращал сумму элементов в списке вместо фактических элементов в списке после исключения указанного целого числа n из списка.

Мне нужна помощь в возвращении оставшихся элементов списка после исключения заданного целого числа n.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Ответ от sashang предполагает встроенный тип F # list. Поскольку вопрос, похоже, использует пользовательский тип с падежами E и L, вот ответ, который вообще не зависит от модуля или типа List. Он также не отображает аккумулятор как параметр верхнего уровня, поэтому вызывающим пользователям не нужно беспокоиться о передаче начального значения:

type ilist = E | L of (int * ilist)

let remove value list =
    let rec remove value acc = function
    | E -> acc
    | L (head, tail) when head = value -> tail |> remove value acc
    | L (head, tail) -> tail |> remove value (L (head, acc))

    list |> remove value E

Как важное примечание, эта функция будет эффективно изменять порядок списка. Если вам нужен порядок сохранения списка, вы можете улучшить функцию для поддержки этого требования.

0 голосов
/ 07 сентября 2018

Вы можете сделать это, используя параметр аккумулятора (acc в приведенном ниже коде). Параметр acc используется для переноса результата предыдущего вызова в рекурсивную функцию, тем самым создавая конечный результат. Это обычная парадигма в функциональном программировании. В этом случае мы запускаем acc с пустого списка и добавляем в него элементы, но пропускаем, когда он соответствует x.

let rec remove x l acc =
    match l with
    | [] -> acc
    | h::t when x = h ->  List.append acc t
    | h::t -> remove x t (List.append acc [h])

Используйте это так:

remove 1 [1;2;3] []

Еще один способ сделать это - использовать List.collect:

let remove_use_collect x l =
    let helper y =
        if x = y then [] else [y]
    List.collect helper l

Однако я думаю, что важно понять 1-й метод и как использовать параметры аккумулятора, поскольку он довольно распространен в функциональном программировании, где вы не можете изменять значения. Вы обнаружите, что многие функции модуля List реализованы где-то с помощью аккумулятора.

...