J'ai besoin d'un algorithme de recherche binaire compatible avec les conteneurs C ++ STL, quelque chose comme std::binary_search
dans l'en- <algorithm>
tête de la bibliothèque standard , mais j'en ai besoin pour renvoyer l'itérateur qui pointe sur le résultat, pas un simple booléen me disant si l'élément existe.
(En passant, à quoi pensait le comité standard quand ils ont défini l'API pour binary_search?!)
Ma principale préoccupation ici est que j'ai besoin de la vitesse d'une recherche binaire, donc bien que je puisse trouver les données avec d'autres algorithmes, comme mentionné ci-dessous, je veux profiter du fait que mes données sont triées pour bénéficier des avantages d'un binaire recherche, pas une recherche linéaire.
jusqu'ici lower_bound
et upper_bound
échouer si la donnée est manquante:
//lousy pseudo code
vector(1,2,3,4,6,7,8,9,0) //notice no 5
iter = lower_bound_or_upper_bound(start,end,5)
iter != 5 && iter !=end //not returning end as usual, instead it'll return 4 or 6
Remarque: je suis également très bien en utilisant un algorithme qui n'appartient pas à l'espace de noms std tant qu'il est compatible avec les conteneurs. Comme, par exemple, boost::binary_search
.
la source
Réponses:
Il n'y a pas de telles fonctions, mais vous pouvez en écrire une simple en utilisant
std::lower_bound
,std::upper_bound
oustd::equal_range
.Une implémentation simple pourrait être
Une autre solution serait d'utiliser un
std::set
, qui garantit l'ordre des éléments et fournit une méthodeiterator find(T key)
qui retourne un itérateur à l'élément donné. Cependant, vos exigences peuvent ne pas être compatibles avec l'utilisation d'un ensemble (par exemple, si vous devez stocker le même élément plusieurs fois).la source
*i == val
! Utilisez plutôt!(val < *i)
. La raison en est quelower_bound
utilise<
, non==
(c'est-àT
- dire qu'il n'est même pas nécessaire d'être comparable à l'égalité). (Voir Effective STL de Scott Meyers pour une explication de la différence entre l' égalité et l' équivalence .)end
. Les plages de la bibliothèque standard C ++ sont représentées avec des intervalles semi-ouverts: l'itérateur de fin "pointe" après le dernier élément. En tant que tel, il peut être retourné par des algorithmes pour indiquer qu'aucune valeur n'a été trouvée.Vous devriez y jeter un œil
std::equal_range
. Il renverra une paire d'itérateurs dans la plage de tous les résultats.la source
Il y en a un ensemble:
http://www.sgi.com/tech/stl/table_of_contents.html
Rechercher:
Sur une note distincte:
Ils pensaient probablement que la recherche de conteneurs pouvait aboutir à plus d'un résultat. Mais dans les rares cas où vous avez juste besoin de tester l'existence, une version optimisée serait également bien.
la source
Si std :: lower_bound est trop bas à votre goût, vous pouvez vérifier boost :: container :: flat_multiset . Il s'agit d'un remplacement de std :: multiset implémenté en tant que vecteur trié à l'aide de la recherche binaire.
la source
L'implémentation la plus courte, se demandant pourquoi elle n'est pas incluse dans la bibliothèque standard:
Depuis https://en.cppreference.com/w/cpp/algorithm/lower_bound
la source
Vérifiez cette fonction, qBinaryFind :
La fonction est incluse dans l'en-
<QtAlgorithms>
tête qui fait partie de la bibliothèque Qt .la source
std :: borne_ inférieure () :)
la source
Exemple: Prenons un tableau, A = [1,2,3,4,5,6,7,8,9] Supposons que vous souhaitiez rechercher l'index de 3 Initialement, start = 0 et end = 9-1 = 8 Now , puisque début <= fin; milieu = 4; (tableau [milieu] qui vaut 5)! = 3 Maintenant, 3 se trouve à gauche du milieu car il est plus petit que 5. Par conséquent, nous ne cherchons que la partie gauche du tableau. Par conséquent, maintenant start = 0 et end = 3; mid = 2. Depuis array [mid] == 3, nous avons donc obtenu le numéro que nous recherchions. Par conséquent, nous retournons son indice qui est égal à mid.
la source
Une solution renvoyant la position à l'intérieur de la plage pourrait être comme ceci, en utilisant uniquement des opérations sur les itérateurs (cela devrait fonctionner même si l'itérateur ne fait pas d'arithmétique):
la source