Rechercher si une chaîne contient un caractère en C ++ (boost autorisé)

Supposons que j’ai une chaîne et que je veux savoir si un caractère spécifique (comme ‘|’) est présent ou non, quelle est la technique la meilleure et la plus rapide pour le faire? Je sais que la chaîne trouve une implémentation. Je demande une implémentation encore plus rapide que celle-ci.

Utilisez std::ssortingng::find

 if (str.find('|') != std::ssortingng::npos) { // ... } 

Il y a peu de chances qu’il y ait plus d’efficacité. O (n) est le mieux que vous puissiez faire. L’implémentation standard de la bibliothèque devrait être à peu près optimale.

Ajoutant la réponse de Tom Tanner. Si vous ne voulez pas faire de calcul a priori, vous serez bloqué à O (n), c’est-à-dire qu’il existe une corrélation linéaire entre la longueur de la chaîne recherchée et la consommation de temps. Tom suggéra de mettre en place un tableau (ou un vecteur) de booléens indiquant si un certain caractère était utilisé. Il faudrait une fois O (n) pour indexer la chaîne, mais vous pouvez ensuite vérifier le nombre de caractères de O (1) (temps constant), le cas échéant. L’inconvénient de cette approche est que vous aurez besoin de beaucoup de mémoire (une fois que vous aurez décidé de prendre en charge le format Unicode).

En guise de compromis, vous pouvez utiliser un std :: set ou similaire, en ne stockant que les caractères existant dans votre chaîne d’entrée. La consommation de mémoire serait alors approximativement linéaire par rapport au nombre de caractères différents dans la chaîne mais la recherche serait O (log n), c’est-à-dire logarithmique dans le temps.

Bien sûr, vous devez mesurer / profiler, puis expliquer ici le cas d’utilisation que vous optimisez réellement. En attendant, gardez ce qui est le plus facile à comprendre et à lire.

Une autre méthode consiste à utiliser la fonction strchr sur la chaîne c_str correspondante:

 if(strchr(str.c_str(), '|')) { \\found } 

Je ne sais pas comment cela se compare à la recherche standard en termes de vitesse, bien que …

La position du personnage trouvé est

 size_t pos = strchr(str.c_str(),'|') - str.c_str(); 

À partir de cette source, un test empirique réalisé avec Visual Studio 2013 Comstackr montre que la routine strchr est environ deux fois plus rapide que l’implémentation std :: ssortingng :: find .

Il n’y a qu’une seule façon de faire cela. Il suffit de parcourir la chaîne pour vérifier si le personnage que vous recherchez existe. Vous pouvez le faire en utilisant la fonction ssortingng::find , qui obtient un caractère et retourne la première position dans la chaîne, ou ssortingng::npos si la valeur n’est pas présente. Vous pouvez également utiliser std::find , qui obtient deux iterators, begin et end , une valeur de clé ‘k’ et renvoie un iterator pointant sur la première occurrence de k dans la plage [begin, end] ou end si k wasn ‘. t trouvé. Et bien sûr, vous pouvez implémenter la fonction de recherche par vous-même, comme ceci:

 ssortingng::size_type pos=ssortingng::npos; for(ssortingng::size_type i=0; i 

ou ca:

 ssortingng::iterator pos=s.end(); for(ssortingng::iterator i=s.begin(); i!=s.end(); ++i) { if(*i == key) { pos=i; break; } } if(pos != s.end()) { // found } else { // not found } 

En savoir plus sur std::ssortingng::find et std::find :

Compte tenu de votre déclaration voulant que vous vouliez quelque chose de plus rapide que ssortingng :: find, la seule chose à laquelle je puisse penser serait de créer une classe dotée d’opérateurs d’affectation hautement personnalisés qui, à chaque mise à jour de la chaîne, mettraient à jour une table interne contenant la première la chaîne de tous les caractères possibles (256 pour une chaîne de caractères, 65536 (?) pour une chaîne large). Cela a O (1) recherche au désortingment de beaucoup de complexité ajoutée aux opérations non const.

Vous pouvez essayer ceci:

  ssortingng s1 = "Hello"; ssortingng s2 = "el"; if(strstr(s1.c_str(),s2.c_str())) { cout << " S1 Contains S2"; }