2010-12-02 2 views
3

A l'intérieur d'une chaîne std ::, est-il possible de trouver le premier d'un ensemble de chaînes sans utiliser de boucle?A l'intérieur d'une chaîne std ::, est-il possible de trouver le premier d'un ensemble de chaînes sans utiliser de boucle?

.: par exemple

std::string str("aaa bbb ccc ddd eee fff ggg"); 
std::vector<std::string> vs; 
vs.push_back("ccc"); 
vs.push_back("fff"); 
size_t pos = 0 
pos = str.find(vs, pos);  //< pseudo code 

Merci!

+0

Quelle langue est-ce? – Gerhard

+0

@Gerhard, c'est C++ –

+1

si vous ne bouclez pas, quelqu'un d'autre le fera. la réponse technique est "non". – tenfour

Répondre

4

Vous pouvez diviser la chaîne (à l'aide d'une chaîne de caractères) en un vecteur, puis utiliser std::find_first_of avec les quatre itérateurs.

Voici un exemple de code complet

#include <iostream> 
#include <string> 
#include <algorithm> 
#include <sstream> 
#include <vector> 
#include <iterator> 

using namespace std; 

int main(void) 
{ 
    string str("aaa bbb ccc ddd eee fff ggg"); 
    vector<string> vs; 
    vs.push_back("ccc"); 
    vs.push_back("fff"); 
    vector<string> scheck; 

    istringstream instr(str); 
    copy(istream_iterator<string>(instr), 
     istream_iterator<string>(), 
     back_inserter(scheck)); 

    vector<string>::iterator it = find_first_of (scheck.begin(), scheck.end(), vs.begin(), vs.end()); 
    if (it != scheck.end()) 
    cout << "first match is: " << *it << endl; 

    return 0; 
} 
4

serait d'utiliser la solution la plus simple une bibliothèque de regex, comme Boost.Regex avec quelque chose comme ceci:

"\\b(ccc|fff)\\b" 
+0

Je pense que dans mon cas cela ne vaut pas la peine d'inclure Boost juste pour ça ... – Pietro

2

Il est pas vraiment possible sauf si vous utilisez une expression régulière. Boost.Regex pourrait être votre ami.

0

Je ne suis pas sûr, mais je pense que:

str.find() retourne un itérateur ("index") à la première instance trouvée.

mais je pense que vous devriez avoir:

size_t pos1 = str.find(vs.begin() , 0); 
size_t pos2 = str.find(vs.end() , 0); 
// since you have only ccc and fff , ccc is on begin(), and fff on end() 

??? mais je ne suis pas sur.

éditer: et je ne pense pas que vous pouvez trouver des occurrences de toutes les chaînes dans le vecteur sans une boucle, sauf si vous faites un déroulement de boucle.

+0

Non, std :: string :: find ne cherchera qu'une seule chaîne. –

0

Quand vous dites sans boucle voulez-vous dire sans une boucle manuscrite parce que les algorithmes utilisent des boucles dans leur mise en œuvre.

Comme vous pouvez le faire pour une chaîne individuelle, vous pouvez faire quelque chose avec vec.begin(), vec.end() str.find et probablement un peu boost :: bind.

Vous ne savez pas exactement ce que vous voulez faire de toutes ces trouvailles. Quelque chose comme ceci:

std::vector<std::string::size_type> locations; 
locations.reserve(vec.size()); 
std::transform(vec.begin(), vec.end(), std::back_inserter(locations), boost::bind(&std::string::find, str, _1)); 

générerait pour vous un vecteur de la position où ces éléments ont été trouvés. Vous pouvez écrire votre propre foncteur si vous voulez quelque chose de plus avancé, par exemple garder l'état, bien que si le code devient vraiment compliqué, je ne vois pas la valeur d'éviter la boucle.

Questions connexes