2010-11-27 16 views

Répondre

19

Je pense que vous avez raison. Il ne peut y avoir aucun partage de la colonne vertébrale de la liste car toutes les queues sont différentes. Par conséquent, la liste des préfixes, si elle est entièrement évaluée, prendrait l'espace Θ (n) complet, qui doit prendre Ω (n) temps à générer.

Notez que (une version lazier de) la fonction que vous avez écrit est disponible en Data.List en tant que inits.

Il y a une optimisation précise que vous pouvez faire. Cette équation est vérifiée:

map (foldl f z) . inits = scanl f z 

Et scanl fonctionne en temps linéaire. Donc, si vous pouvez exprimer la chose que vous voulez faire à chaque préfixe comme un pli gauche, alors vous pouvez éviter la complexité quadratique de la construction de la liste des préfixes.

+2

+1 bonne idée avec scanl –

3

N'est-ce pas dépendant de la représentation? Si vous représentez des listes en tant que stockage contigu plus index de début et de fin (similaire à bytestrings), vous pouvez partager le stockage et simplement devoir parcourir une fois pour créer la liste d'index. L'algorithme ne changerait pas, juste la représentation. Pour ce cas d'utilisation particulier, l'utilisation de listes snoc (listes binaires, mais imbriquées à la fin, pas au début, de la liste) permettrait également le partage de sous-listes, n'est-ce pas?

+0

Je pense que c'est relativement clair, que sa question cible une liste de haskell ordinaire '[]'. -1 – fuz

+2

Cela dépend si vous regardez la syntaxe de l'exemple ou à la question comme indiqué. Compte tenu de la réponse acceptée, la limitation aux listes binaires peut avoir été prévue. Mais ce n'est pas une propriété des algorithmes purement fonctionnels, pas même de tels algorithmes dans Haskell, juste de cette représentation de liste particulière. – claus

+0

Oui, la limitation aux listes binaires était prévue. J'aurais pu le préciser. –