Erlang - элемент и список - PullRequest
       3

Erlang - элемент и список

4 голосов
/ 26 октября 2011

Я новичок в эрланге.Интересно, как написать функцию, которая возвращает первые N элементов в списке?

Я пробовал:

    take([],_) -> [];
    take([H|T],N) when N > 0 -> take([H,hd(L)|tl(T)], N-1);
    take([H|T],N) when N == 0 -> ... (I'm stuck here...)

Есть подсказка?thx

Обновление: я знаю, что есть функция с именем "sublist", но мне нужно выяснить, как написать эту функцию самостоятельно.

Я наконец-то понял ответ:

-module(list).
-export([take/2]).

take(List,N) -> take(List,N,[]).
take([],_,[]) -> [];
take([],_,List) -> List;
take([H|T], N, List) when N > 0 -> take(T, N-1, lists:append(List,[H]));
take([H|T], N, List) when N == 0 -> List.

Ответы [ 2 ]

25 голосов
/ 26 октября 2011

В Эрланге пишется take lists:sublist:

L = [1, 2, 3, 4];
lists:sublist(L, 3).   % -> [1, 2, 3]
8 голосов
/ 26 октября 2011

Простое решение:

take([H|T], N) when N > 0 ->
    [H|take(T, N-1)];
take(_, 0) -> [].

Это приведет к ошибке, если в списке недостаточно элементов.

Когда вы используете аккумулятор, как вы делаете, вы обычно не добавляете элементы в его конец, так как это очень неэффективно (вы копируете весь список каждый раз). Обычно вы добавляете к нему элементы с помощью [H|List]. Тогда он будет в обратном порядке, но затем вы делаете lists:reverse(List), чтобы вернуть их в правильном порядке.

take(List, N) -> take(List, N, []).

take([H|T], N, Acc) when N > 0 ->
    take(T, N-1, [H|Acc]);
take(_, 0, Acc) -> lists:reverse(Acc).

Аккумуляторная версия - хвостовая рекурсия , что хорошо, но вам нужно сделать дополнительный реверс, который устранит некоторые из преимуществ. Первая версия, я думаю, более понятна. Нет четкого обоснования для любого из них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...