Du point de vue théorique, on ne peut pas savoir si length
est θ (n), nous savons qu'il est O (n), mais il est techniquement possible que Haskell met en œuvre plus rapide pour les listes connues.
Depuis un compilateur Haskell pourrait être libre d'implémenter une liste comme ils le veulent. Mais néanmoins il n'a pas d'importance, puisque dans ce cas générant la liste en premier lieu prendra θ (n).
Notez que même si le compilateur utilise une structure de données plus dédié, Haskell est paresseux, de sorte que votre compréhension de la liste ne donne pas lieu à une liste complète, mais plus dans une fonction qui peut générer une liste paresseusement.
Enfin, si nous évaluions la compréhension de la liste avec impatience, il faudrait à nouveau O (n) pour d'abord générer la liste en premier lieu. Donc, même si l'obtention de la longueur était très rapide, la génération de la liste nécessiterait O (n) comme limite inférieure. Donc, quelle que soit l'efficacité de length
, l'algorithme va encore évoluer linéairement avec l'entrée.
Votre propre implémentation utilise à nouveau O (n) (et n'est pas très sûr pour être honnête). Néanmoins, vous pouvez facilement speedup la factorisation d'un nombre à O (sqrt n):
factors :: Int -> Int
factors x = go 1
where
go :: Int -> Int
go i | i2 > x = 0
| i2 == x = 1
| mod x i == 0 = 2 + go (i+1)
| otherwise = go (i + 1)
where i2 = i*i
nous énumérons ici de 1 à sqrt (n). Chaque fois que nous trouvons un facteur a
, nous savons qu'il y a un co -facteur b = x/a
. Tant que a
n'est pas égal à sqrt (x), nous savons que ceux-ci sont différents. Dans le cas a
est égal à sqrt (x), nous savons que a
est égal à b
et ainsi nous comptons cela comme un. Cela étant dit, il y a certainement des moyens plus rapides de le faire. C'est un sujet avec beaucoup de recherche qui a donné des algorithmes plus efficaces. Je ne suggère pas que ce qui précède est le plus rapide, mais c'est certainement une énorme amélioration en termes de complexité temporelle.
Mais ce n'est pas une chaîne. –
Qu'en est-il de ArrayList.size(), alors? Le point est la complexité, pas le type spécifique. – cHao
Il semble probable qu'après l'optimisation du code par le compilateur, l'évaluation de la première expression 'factors' n'impliquera même pas la construction d'une liste.Gardez à l'esprit le fonctionnement de l'évaluation paresseuse - vous ne "construisez pas une liste, vous ne comptez pas sa taille" - vous comptez les éléments de la liste * au fur et à mesure qu'ils sont générés *. –