6
votes

Y a-t-il une fonction qui est à std :: Rechercher ce que STD :: compter est à STD :: Trouver?

Si le titre semble bizarre, voici une autre explication:

Si j'ai une plage a , et je veux compter combien de fois une autre plage B est apparue dans la plage a , y a-t-il un std :: fonction pour le faire?

Si non, y a-t-il un moyen simple de le faire (OFC I peut boucle manuellement en boucle manuellement en utilisant std :: Rechercher - Je parle de quelque chose de plus élégant)?


3 commentaires

Je suppose qu'il n'y a pas de fonction standard de ce type, car il n'est pas clair si cela devrait compter des allumettes recouvertes


@Anatolyg True, en fait, la motivation pour cela me faisait aider certains jeunes programmeurs aspirants à compter tous les mots dans une séquence ... et nous avons discuté de ("AAAB", "AA") 2 ou 1.: D


@Anatolyg svn.boost.org/trac/boost/ticket/7784 . ..


4 Réponses :


1
votes

Vous pouvez utiliser std :: comte_if sur la plage A avec une lambda qui utilise std :: Trouver sur la plage b.

EDIT: remplacé std :: Recherche avec std :: Trouver.


0 commentaires

3
votes

Je pense que vous aurez besoin de construire votre propre. Voici ce qui vient à mon esprit comme une implémentation.

int main() {
    std::vector<int> haystack = {1, 19, 7, 23, 2, 19, 19, 19, 19};
    std::vector<int> needle   = {19, 19};

    assert(subsequence_count(begin(haystack), end(haystack), begin(needle), end(needle) == 3);
}


0 commentaires

1
votes

Si vous voulez le faire plus efficacement que O (nm) , pour m caractères dans le motif, n dans la chaîne à Soyez recherché, vous pouvez envisager un arbre suffixe . Cela signifie essentiellement que vous construisez une structure d'arborescence spécialisée qui décrit simultanément tous les suffixes possibles d'une chaîne. Donc, si votre chaîne est "ratatat", votre chaîne de suffixe représentera simultanément "ratatat", "Atatat", "Tatat", "Atat", "TAT", "TAT", "AT" et "T". Vous pouvez donc trouver (et compter) toutes les occurrences d'une chaîne particulière très rapidement une fois que vous avez construit l'arbre. Bien sûr, il faut un effort de programmation et une mémoire!

Il y a une très belle description ici ( Cela fait référence au livre de Skiena Le manuel de design d'algorithme , qui est là que j'ai lu à leur sujet).

PS J'ai commencé à rechercher des implémentations suffixe de l'arbre C ++. Il existe plusieurs questions utiles sur StackoverFlow à ce sujet, mais rien dans STD dans la mesure du possible.

modifier pour ajouter algorithme alternatif

sur deuxième pensées, je pense que boyer-moore String Correspondant est probablement une meilleure solution, notamment car il y a un 5 commentaires


0
votes

En cas de doute, utilisez Boost :)

#include <boost/algorithm/string/finder.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/foreach.hpp>

using namespace std;
using namespace boost;
using boost::algorithm::find_all;

int main(int argc, char* argv[])
{
    std::vector<double>  haystack{11.0,22.0,33.0,22.0,33.0,44.0,22.0,33.0,22.0};
    std::vector<double> needle{22.0,33.0};

    std::vector<boost::iterator_range<std::vector<double>::iterator>> out;
    boost::algorithm::find_all(out, haystack, needle);

    cout << "matches=" << out.size() << endl;
    cout << endl;

}


0 commentaires