2012-06-21 21 views
6

Wdrażaj listę słów Erlanga, która pobiera dwa elementy z listy i tworzy nową listę list.Erlang: jak wdrożyć zrozumienie listy Erlanga?

Mam ten kod

pair([], Acc) -> lists:reverse(Acc); 

pair(L, Acc0) -> 
    [ A, B | T ] = L, 
    Acc = [ [A, B] | Acc0 ], 
    pair(T, Acc). 

który działa prawidłowo:

7> l:pair(lists:seq(1,6), []). 
[[1,2],[3,4],[5,6]] 

ale wydaje się, że powinienem być w stanie realizować to jako listowego. Mój Erlang-fu jest zbyt słaby, by to wymyślić.

Wszelkie sugestie?

Dzięki

Odpowiedz

1

Lista zrozumienie będzie przylegający ponieważ nieuchronnie musi coś zrobić dla każdy element listy. Aby utworzyć spisane zrozumienie, musisz spróbować dowiedzieć się, czy jest to element parzysty czy nieparzysty, z którym rozmawiasz. Oto pomysł, co mówię:

pair(L) -> 
    L2 = lists:zip(lists:seq(1, length(L)), L), 
    [[A, B] || {Ai, A} <- L2, {Bi, B} <- L2, 
      Ai rem 2 == 1, Bi rem 2 == 0, Ai + 1 == Bi]. 

Złożoność czas na ten jeden jest prawdopodobnie straszne bo o ile jestem świadomy Erlang nie optymalizuje to w żaden sposób.

Nie sądzę, że coś jest nie tak z twoją funkcją i powinieneś się jej trzymać.

8

Nie, zrozumienie list nie byłoby dobrym sposobem na zrobienie tego, z definicji działają one tylko na jednym elemencie. W twoim kodzie naprawdę nie ma potrzeby używania akumulatora, różnica w prędkości jest niewielka, here, a staje się jaśniejsza bez niego. Tak przynajmniej myślę.

pairs([A,B|L]) -> 
    [[A,B]|pairs(L)]; 
pairs([]) -> []. 
+1

Jest to zgodne z mantrą Erlang "zawieść", np. dla przypadku "[a]". – Tilman

+0

@Tilman Tak, funkcja jest ** zdefiniowana **, aby wziąć pary elementów, więc jeśli jest to błąd, jeśli na liście znajduje się nieparzysta liczba elementów. Oczywiście możesz zawsze zdefiniować, co ma się stać w tym przypadku, a potem to zrobić. – rvirding