comment sélectionner un sous-ensemble d'un std::vector ou de la liste?
c++ gourous:
il ya tout à fait utile, c++ stl algorithmes tels que de trouver ou de recherche. Cependant, il semble qu'ils ne retournent une seule interator.
ce que si je veux faire un SQL de style 'select' pour un conteneur STL? dire, un vecteur (pourrait être étendu à la liste ou sur la carte). quelque chose comme
std::pair<vector::iterator, vector::iterator> select(std::vector::iterator begin, std::vector::iterator end, Comparor equal_to)
la sortie doit être une plage, quelque chose comme un std::pair, ce qui est similaire à la valeur de retour des méthodes de boost::multi-index
est-il quelque chose comme cela dans la stl? ou tout solide libararies similaire?
Que faire si le sous-ensemble n'est pas une ligne de sous-intervalle?
Il n'y a rien de ce genre dans la bibliothèque standard. Une option serait de boost::Plage, et spécifiquement boost::fourchette::filtré
les éléments de sortie sont censés être, le plus souvent, pas continugous
si les éléments de sortie ne sont pas contiguës, comment sur terre attendez-vous d'une paire de
J'devraient avoir expliquer mon problème le plus précisément: je veux la sortie d'un conteneur de itérateurs, plutôt qu'un conteneur de profondément les objets copiés (qui est va être énorme)
Il n'y a rien de ce genre dans la bibliothèque standard. Une option serait de boost::Plage, et spécifiquement boost::fourchette::filtré
les éléments de sortie sont censés être, le plus souvent, pas continugous
si les éléments de sortie ne sont pas contiguës, comment sur terre attendez-vous d'une paire de
vector::iterator
objets pour vous dire lesquels ils sont en dehors de l'ensemble de vecteur? La seule façon d'y parvenir serait de copier ou de déplacer les éléments égaux dans les parties contiguës d'un vecteur, qui vous l'ai dit ailleurs, est trop cher.J'devraient avoir expliquer mon problème le plus précisément: je veux la sortie d'un conteneur de itérateurs, plutôt qu'un conteneur de profondément les objets copiés (qui est va être énorme)
OriginalL'auteur James Bond | 2013-11-23
Vous devez vous connecter pour publier un commentaire.
Vous avez essentiellement deux approches:
1) La chose que vous dites dans un commentaire ci-dessus, écrire (des itérateurs de pointage) les résultats dans un récipient d'itérateurs. Ça va ressembler à quelque chose comme ceci:
Puis vous l'appeler comme:
Vous pouvez réellement définir
select_iterators
en termes de d'autres algorithmes, à l'aide decopy_if
etboost::counting_iterator
, mais je ne pense pas que ça vaut le coup lors de la mise en œuvre directe est si simple. Il devrait ressembler à:2) au Lieu de tester toutes les valeurs à l'avant et à l'écrit les résultats quelque part, de définir un itérateur qui avance plus de la gamme d'origine à chaque fois qu'il est incrémenté jusqu'à ce qu'il trouve le prochain match. Boost fournit deux façons de le faire,
boost::filter_iterator
etboost::adaptors::filter
. Donc, vous pourriez écrire:Tout ce que vous voulez faire avec vos résultats, vous pouvez effectuer une itération de
results.begin()
àresults.end()
comme s'il s'agissait d'un conteneur. Ce n'est pas un conteneur, il n'est pas satisfaire tout le contenant de l'interface. Il répond à une interface définie par coup de pouce, d'une Plage nommée, ce qui équivaut à "peut être itéré". Il s'agit en fait simplement d'une vue filtrée demyfoos
, donc pas deFoo
objet est copié ou même déplacé.std::copy_if(src.begin(), src.end(), dst.begin(), pred)
?en raison de l'observation faite par le premier interlocuteur, "je veux que la sortie d'un conteneur de itérateurs, plutôt qu'un conteneur de profondément les objets copiés"
Ohhh, merci
cela m'a pris un prudent de lire pour comprendre, bien que, malgré le fait que j'ai écrit ça 🙂 Autres que la valeur de retour, la différence entre ma première mise en œuvre de
select_iterators
etcopy_if
est juste que la mienne a= first
oùcopy_if
aurait= *first
.OriginalL'auteur Steve Jessop
Si vous pouvez modifier votre vecteur std::partition serait le choix. Voici comment vous l'appelez:
Vous êtes la réponse se situent entre
v.begin()
etp
.La complexité est expliqué dans la page liée. Si votre copie de l'algorithme est coûteux, kt n'est pas un bon choix.
OriginalL'auteur Johan
Vous pourriez être à la recherche pour
boost::range
Un
boost::range
est effectivement une paire d'itérateurs de délimitation d'une gamme d'éléments d'un conteneur. La bibliothèque comprend des algorithmes différents, qui renvoient une gamme à partir d'une plage (tels que la gamme de valeurs équivalentes en conteneur, avec une fourni par l'utilisateur équivalence foncteur).OriginalL'auteur rici
Choses à garder à l'esprit:
1.) Vous avez dit que vous voulez que votre conteneur de
iterator
plutôt queconst_iterator
. Le type sera le même que le point de début et de fin de la plage de passer à la fonction. Par exemple, le type seraconst_iterator
pourconst
conteneurs, il sera égalementconst_iterator
si vous utilisezvector::cbegin
etvector::cend
, et il ne compile pas si vous utilisez différentes itérateurs commevector::begin
etvector::cend
.2.) Vecteurs perdent souvent leur itérateur de validité, donc soyez prudent avec l'utilisation de ces itérateurs. Si vous ajoutez le vecteur, par exemple, chaque itérateur renvoyé par cette fonction pourrait être nulle. Pour éviter cela, utilisez un autre conteneur (par exemple, liste) ou de l'utilisation
vector::reserve
.3.) L'avant itérateur doit être quelque chose qui prend en charge ++, et quand déréférencé, a le même type que InputIterator (par exemple
vector<int>::iterator
). Il doit également rester valide itérateur après l'incrémentation ou la fonction serait vide de sens. La sortie itérateur doit aller à un endroit avec assez d'espace pour contenir tous les itérateurs trouvé pour satsifypred
. Si vous ne connaissez pas l'espace à l'avance, vous pouvez utiliserstd::back_inserter
de<iterator>
avec un conteneur qui acontainer::push_back
défini, et il va augmenter si nécessaire.Voici un test de la fonction pour vous de comprendre comment il fonctionne.
OriginalL'auteur user904963