Le livre que je lis sur Erlang a des exercices à l'arrière de celui-ci et il est nécessaire de recréer les listes: Ajoutez la fonction.
Je pourrais le faire simplement en utilisant l'opérateur ++, mais n'est-ce pas vraiment lent? Et je pense que le point de l'exercice est de le faire à l'aide d'opérations de liste que j'écris. P>
Jusqu'à présent, la seule approche que je pouvais penser est de faire quelque chose comme: p> mais je sais que c'est incorrect ... p> Toute suggestion sur la façon de faire cela? P> Edit: Pour clarifier la question, voici un Exemple d'entrée et de sortie: P> entrée: [[[1,2,3], [], [4,5], [6]]]
Sortie: [1,2,3,4,5,6] P> Après avoir travaillé un moment, j'ai également proposé ce code: p> Toutefois, cela ne fonctionne que lorsque la liste est la taille 3. Comment puis-je modifier ceci afin qu'il fonctionne pour une quantité donnée de listes de taille au hasard? P> p>
4 Réponses :
Vous n'avez besoin que de deux paramètres sur votre fonction Concat, car vous allez être ajouté à l'un des paramètres et c'est ce que vous allez finalement revenir. Quelque chose comme (non testé): Le ++ est l'opérateur de l'annexe, vous allez devoir faire cela pour être efficace. P> (L'idée de la ci-dessus consiste à renvoyer le paramètre de gauche si nous n'avons plus de choses à gauche, ou appelez à nouveau après avoir déplacé l'un des éléments de droite à gauche). Il y a probablement plus d'efficacité autour de faire l'annexe en sens inverse et enfin en inversant la réponse, mais hey ...) p> (vient de voir votre édition, et le mien bien sûr ne fonctionne que pour deux choses à ajouter, mais vous pouvez Recurrez à travers la fonction ci-dessus pour chaque élément de votre liste de listes ...) p> p>
Il n'avait pas besoin de crochets autour du H (au moins quand je l'ai couru) et travaillé assez bien! Merci!
Mais il y a plus! Sur le chemin du travail, j'ai pensé à ajouter cette clause de fonction: Concat (L, [H | T]) lorsque IS_List (H) -> Concat (Concat (L, H), T)). Et cela gérerait quelque chose comme la matrice imbriquée que vous aviez: Concat ([], [1,2,3, [1,2], [1,2, [1,2]]]). (C'est-à-dire que c'est vraiment un aplatir ...)
Cette utilisation est-elle efficace de ++? La liste de gauche en ++ est en cours de copie. erlang.org/doc/efficient_guide/listhandling.html
++ n'est lent que lorsque vous êtes utilisé à tort, utilisé avec précaution, il est aussi rapide que tout ce que vous pouviez emprunter à la main. Vous devez vous assurer de travailler dans la liste dans la bonne direction, sinon l'annexe résultante est O (n ^ 2). Lorsque nous faisons x ++ y, nous devons effectuer une copie de x puis la préparer à Y qui n'est pas copiée.
Dans cette fonction, l'accumulateur apparaît sur le côté gauche de la ++, de sorte que l'annexe est donc à l'annexe. non efficace. p> Cette fonction fonctionne beaucoup mieux, même si ce n'est pas de la queue récursive. p> Dans ce cas de réécriture Pour être une queue récursive n'est qu'une amélioration modeste: p> Les timings sur une grande liste d'entrée montrent à quel point l'amélioration est énorme. (Les temps sont en microsecondes.) P>
Je lis le livre O'Reilly Erlang et je me souviens de lire que si vous souhaitez préparer un nouvel élément à la tête d'une liste, utilisez la notation des inconvénients, tels que: [H | ACC] au lieu de ++. Comment cela affecterait-il les résultats que vous avez donnés?
Utiliser | Pour prétendre un seul élément, ++ pour préparer une liste d'éléments. Autre que ce qu'ils sont identiques. [A] ++ b = [a | b]. Vous pouvez implémenter ++ en utilisant | (Assurez-vous de construire dans la bonne direction), auquel cas vous obtiendrez quelque chose du même ordre que ++, mais plus lentement, car ce n'est pas intégré.
Si vous préparez un seul élément, [A] ++ B est précisément équivalent à [A | B]. En fait, je m'attendrais à ce que le compilateur le converse au formulaire [A | B] lors de la compilation.
Une approche soignée consiste à utiliser C'est aussi une bonne exercice pour écrire votre propre fonction de pli ... p> < / p> listes: replier code>,
-module(functional). -export([my_append/2,helper/2]). my_append(L1,L2) -> % concatenates lists L1 and L2 functional:helper(lists:reverse(L1),L2). helper(L1,L2) -> if L1 == [] -> L2; L2 == [] -> L1; true -> [H1|T1] = L1, functional:helper(T1,[H1|L2]) end.
Je n'utilise pas Erlang, mais je ne peux pas imaginer que
listes: Ajout code> est plus rapide que
++ code> (je pense que c'est O (n), quoi que ce soit ce).
Mais ++ peut être inefficace si son opérande gauche est plus grand que son bon opérande. Cette pénalité de performance a-t-elle également lieu avec des listes: appendez-vous?
Oui. Erlang fera de mieux en ce qui concerne la structure de données en question, une liste immuable à une liste localisée. À la suite de ces listes: ANNEXE ([x, Y]) est nécessairement O (longueur (x)).
Comme indiqué par @Alexeyromanov Voir le code: référentiel Erlang
erl -noshell -val 'io: fwrite ("~ p ~ n", [nom de fichier: rejoindre (lib_dir (stdlib), "src", "list.erl"])])' -S init arrêter code>