2010-09-22 7 views
4

J'essaie de renvoyer le maximum d'une liste.renvoyant le maximum d'une liste

J'ai le code suivant

list_max([]) -> 
    []; 
list_max([H|T]) -> 
    list_max(H, T). 
list_max(Temp, []) -> 
    Temp; 
list_max(Temp, [H|T]) when H > Temp -> 
    Temp = H; 
list_max(Temp, T). 

Mais me bats pour se rapporter à Erlang.

Comment attribuer quelque chose à la température et la remplacer par la plus élevée?

Répondre

3

Erlang est l'une de ces langues dans lesquelles je trouve plus facile à montrer qu'à expliquer.

list_max([] ) -> empty; 
list_max([H|T]) -> {ok, list_max(H, T)}. 

list_max(X, [] )   -> X; 
list_max(X, [H|T]) when X < H -> list_max(H, T); 
list_max(X, [_|T])   -> list_max(X, T). 

et l'appeler ainsi:

{ok, Max} = list_max(MyList). 
+0

@ daniel-luna exemple est le meilleur. C'est en fait l'implémentation native de Erlang des listes: fonction max (L). Pourquoi c'est mieux? Veuillez noter l'ordre d'itération.Dans votre cas, vous devrez entrer FIRST pour chaque itération à la fin de la liste. Les meilleurs cas d'itération sont dans l'exemple de daniel-luna –

1

Vous pouvez également exprimer que dans des fonctions intégrées:

-module(list_max). 
-compile(export_all). 

list_max([]) -> none; 
list_max([H | T] = List) -> 
    lists:foldl(fun erlang:max/2, H, T); 
list_max(_) -> badarg. 
+0

Puisque 'max' est associatif, vous devriez utiliser' foldl' à la place. –

+0

C'est beaucoup pour moi de prendre mais merci. Juste commencé à faire erlang ce terme en Uni. – jarryd

+0

@Marcel Cantos Vous avez raison. Je vais corriger cela. – stmi

3

Comment puis-je attribuer quelque chose à température et de le remplacer à la le plus élevé?

La réponse courte est que vous ne pouvez pas. Les variables dans Erlang ne peuvent pas être changées une fois assignées.

La réponse un peu plus longue est que, même si vous ne pouvez pas modifier une variable dans un appel de fonction particulier, vous pouvez toujours effectuer une auto-recurse. La récursion-queue à Erlang est optimisée.

Dans l'exemple de code que vous avez fourni, list_max ne regarde que les deux premiers éléments de la liste. Les quatrième et cinquième clauses doivent à nouveau appeler list_max, avec la nouvelle valeur de Temp dans le premier paramètre. C'est une chose commune à faire dans les langages fonctionnels. Dans ce cas, Temp est connu comme un Accumulateur (je nomme souvent la variable Acc pour refléter cette utilisation, mais bien sûr vous pouvez l'appeler comme vous voulez).

Permettez-moi de montrer une autre solution qui pourrait être considérée comme « entre » la réponse de Macelo et la réponse de STMI:

list_max([H|T]) -> list_max(H , T). 

list_max(X , [] ) -> X; 
list_max(X , [H|T]) -> list_max(erlang:max(H, X) , T). 

(j'ai aussi abandonné la clause qui détecte la liste vide, parce que je ne pense pas vraiment vous achète beaucoup - bien qu'il va maintenant lancer une exception si vous l'appelez avec une liste vide.)

1

Erlang est une affectation unique de sorte que vous ne pouvez pas changer de "variables". Vous ne pouvez en créer que de nouveaux.

Ma recommandation est de regarder le module des listes. A l'intérieur lists.erl vous trouverez:

max([H|T]) -> max(T, H). 

max([H|T], Max) when H > Max -> max(T, H); 
max([_|T], Max)    -> max(T, Max); 
max([], Max)    -> Max. 

Vous ne mettez pas à jour la variable Max (Temp dans votre exemple), mais plutôt d'appeler la fonction avec la nouvelle valeur ou le retourner de la fonction.

... :-) Facile comme bonjour

+0

Ceci est le bon exemple. C'est en fait l'implémentation native de Erlang des listes: fonction max (L). Pourquoi c'est mieux? Veuillez noter que l'ordre d'itération offre la meilleure performance par rapport à toutes les autres solutions affichées ici. –

2

Désolé, peut-être que je me manque quelque chose. Cherchez-vous:

lists:max(List). %% Find the max in List 
+0

Non, je dois le faire moi-même. : P – jarryd

+0

Bon! : D Merci. Maintenant, je suis capable de comprendre la documentation hahaha –