La definición de <
para std::pair
implementa una orden lexicográfica y ""
es el elemento mínimo para las cadenas. Combinando esto obtenemos:
typedef std::pair<std::string, std::string> StringPair;
typedef std::set<StringPair> Set;
std::string const* find_first(Set const& s, std::string const& key) {
Set::const_iterator const it = s.lower_bound(std::make_pair(key, ""));
// Check that it actually points to a valid element whose key is of interest.
if (it == s.end() or it->first != key) { return 0; }
// Yata!
return &it->second;
}
El truco está utilizando lower_bound
adecuadamente.
Devuelve un iterador que apunta al primer elemento que no se compara con menos de value
.
- Si devuelve
end()
, entonces no se encontró nada interesante.
- De lo contrario,
it->first >= key
por lo que deshacerse de la caja >
(de ningún interés para nosotros)
me gustaría señalar sin embargo que esto sólo devuelve el primer elemento de la gama. Si usted está interesado en todos los elementos, tratar:
typedef std::pair<Set::const_iterator, Set::const_iterator> SetItPair;
SetItPair equal_range_first(Set const& s, std::string const& key) {
StringPair const p = std::make_pair(key, "");
return std::make_pair(s.lower_bound(p), s.upper_bound(p));
}
Esto devolverá toda la gama de nodos en s
cuyo primer elemento es igual a key
. A continuación, sólo tiene que iterar sobre esta gama:
for (Set::const_iterator it = range.first; it != range.second; ++it) {
// do something
}
Y que ni siquiera tiene que preocuparse de si el retorno de lower_bound
o upper_bound
era el final o no.
- si
lower_bound
rendimientos end()
, entonces también lo hace upper_bound
, y el bucle se salta
- si
lower_bound
apunta a un nodo para el que it->first > key
, entonces upper_bound
señalarán a ese mismo nodo, y el bucle se salta
Esa es la potencia de los rangos: no es necesario hacer comprobaciones especiales, los rangos simplemente terminan vacíos cuando no hay coincidencia, por lo que el ciclo sobre ellos ... se omite en una sola comprobación.
¿Por qué no estás usando un 'map'? Otras notas: si es un 'std :: set', ¿por qué se llama' myList'? ¿Has creado una función de comparación para 'std :: pair's? ¿Como se ve eso? –