Supposons que j'ai un std::vector
dire Vector
Maintenant, après avoir effectué certaines opérations sur le vecteur (insertion ou suppression), je souhaite vérifier si le vecteur est vide et sur cette base, je souhaite effectuer certaines opérations.
Quelle approche est la meilleure
Approche 1
if (Vector.size() == 0){ /* operations */ }
Approche 2
if (Vector.empty()) { /* operations */ }
Quelle est la meilleure approche, 1
ou 2
?
v.size() == 0
dit "Je compare la taille", mais le fait pour vérifier si le conteneur est vide. Il existe un petit algorithme à digérer (très petit, car il ne s'agit que d'une comparaison) avant de savoir ce qu'il fait.
OTOH, v.empty()
fait exactement ce qu'il dit: il vérifie si v
est vide.
Pour cette raison, je préfère clairement le n ° 2, car il fait ce qu'il dit. C'est pourquoi empty()
a été inventé, après tout.
Mais il y a aussi une raison algorithmique de préférer empty()
: Si quelqu'un change plus tard std::vector
en std::list
, v.size()
pourrait avoir O (n). (En C++ 03, il est garanti que ce soit O(1) pour std::vector
, mais pas pour std::list
. Selon le commentaire de James à la réponse de Prasoon ce sera O(1) pour tous les conteneurs en C++ 1x.
Je dirais que l'approche no 2, car méthode empty () a été délibérément conçue pour vérifier si un vecteur est vide. Vous pouvez également vérifier l'efficacité des deux approches, puis décider laquelle est la meilleure.
L’approche (2)
serait préférable car empty()
est toujours exécuté dans un temps constant [i.e O(1) ] quel que soit le type de conteneur.
size()
s'exécute également dans O(1)
[pour std :: vector] bien qu'il puisse s'exécuter dans O(n)
pour std:list
[l'implémentation étant définie comme telle]
Dans Effective STL
[Point 4] Scott Meyers dit
Vous devriez préférer la construction utilisant empty, et la raison est simple: empty est une opération à temps constant pour tous les conteneurs standard, mais pour certaines implémentations de liste, la taille prend du temps linéaire.
.....
Peu importe ce qui se passe, vous ne pouvez pas vous tromper si vous appelez vide au lieu de cocher la case voir si size () == 0. Appelez donc vide chaque fois que vous avez besoin de savoir si un conteneur a zéro élément.
Généralement, un vecteur est implémenté de manière interne en tant que pointeur sur un tableau alloué de manière dynamique, et les membres de données contenant les capacity
et size
du vecteur La size
du vecteur est le nombre réel d'éléments, tandis que la capacité fait référence à la taille du tableau dynamique.
Étant donné cette implémentation, la fonction membre size()
sera simplement un getter pour le membre size
.
empty()
renverra le résultat de la comparaison size == 0
.
Donc, les deux sont aussi efficaces que O(1)
mais il est recommandé de empty()
si vous voulez vérifier si le vecteur est vide. Parce que c'est ce que la fonction est là pour. Cela rendra votre code plus facile à lire.
Si vous débutez dans la programmation, utilisez-en une qui a plus de signification pour vous. Par exemple, si == 0 est plus significatif pour vous que .empty (), utilisez-le.
Plus tard, si vous avez des problèmes de performances (ce dont je doute fort que vous ayez ici), utilisez-en un qui réponde à vos objectifs de performances.
En réalité, vector.empty () et vector.size () == 0 font la même chose . empty compare le début et la fin et renvoie la valeur true si elles sont identiques, la taille calcule le début à la fin. La valeur renvoyée est 0 si elle est vide et effectue la même chose avec un autre calcul.
Juste pour le plaisir: pourquoi pas:
if(Vector.begin() == Vector.end())
?
Optez pour vide ().