7
votes

STL SET INTERSECTION ET LA SORTIE

J'ai un extrait de code comme celui-ci, pour être compilé sous VC ++ 2010.

std::set_intersection<std::set<int>::const_iterator, std::set<int>::const_iterator, std::set<int>::iterator>(
  s1.begin(), s1.end(), s2.begin(), s2.end(), res_set.begin()
);


0 commentaires

3 Réponses :


11
votes
    std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), std::inserter(res_set, res_set.end()));

0 commentaires

8
votes

res_set.begin () code> ne peut pas être utilisé comme argument de sortie de set_intersection code> pour deux raisons:

  • L'ensemble est vide, ce qui essaierait d'écraser les éléments existants de l'ensemble li>
  • Vous ne pouvez pas modifier des éléments d'un ensemble. Li> ul>

    à la place, vous voulez un insert_iterator code>, pour insérer les nouveaux éléments dans le jeu: P>

    std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), 
                          std::inserter(res_set, res_set.end()))
    


0 commentaires

8
votes

L'argument de sortie à un std :: set_intersection doit être à un mutable valeur_type . Les itérateurs de std :: set ne supportent jamais la mutation, depuis que le changement de valeur d'un élément pourrait changer où il appartenait l'ensemble. Fonctions dans le groupe avec std :: set_iteratorator sont conçus travailler sur des séquences triées, par exemple. std :: vecteur .

Dans votre cas, vous pouvez remplacer votre std :: Set avec std :: vecteur , les trier au besoin (et éventuellement utiliser std :: inférieur et insertion à les garder triés face à l'insertion) ou à utiliser std :: insert_iterator (res_set, res_set.end ()) .


4 commentaires

Pour le compte rendu, j'avais pensé que l'intersection de deux ensembles doit avoir une forme triviale. Je suis un peu surpris qu'il n'y ait aucune méthode d'intersection qui traite de l'ensemble par défaut. Soit j'ai manqué quelque chose ou c'est une lacune de la STL.


James, les fonctions définies sont conçues pour être utilisées sur des ensembles autant qu'ils doivent être utilisés sur des vecteurs triés. Changer simplement que l'ensemble sur un vecteur ne résoudra rien. Ce qui ne va pas, c'est juste le paramètre final, qui ne peut pas être écrit à. Un insert Itérateur corrige cela pour un ensemble ou un vecteur.


std :: Set n'est pas vraiment un ensemble dans le sens mathématique. Ou du moins, ce n'est que partiellement un. En général, en informatique, un ensemble est simple une collection non ordonnée sans doublons et une recherche plus ou moins rapide. STD :: SET ajoute la commande, mais remplit sinon cette définition. (Pascal a eu des ensembles dans le sens mathématique, mais ils étaient limités à de petits entiers. Plus comme std :: bitset .)


@ROBKENNEDY C'est un problème supplémentaire: avec std :: vecteur , vous pouvez écrire quelque chose comme res_set.réesize (S1.Size () + s2.Size ()); res_set.herase (STD :: Set_InterSection (S1.BeGIN (), S1.end (), S2.EGIN (), S2.end (), Res_set.begin ()), RES_SET.END ()) . De toute façon, la contrainte pour S1` et s2 est que les données sont triées: Utilisation std :: Set est un moyen d'y parvenir (et souvent le le plus simple et le meilleur), mais pas le seul moyen.