La definizione di <
per std::pair
implementa un ordine lessicografico e ""
è l'elemento minimo per le stringhe. Combinando questo otteniamo:
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;
}
Il trucco sta usando lower_bound
in modo appropriato.
restituisce un iteratore che punta al primo elemento che non meno di confrontare value
.
- Se ritorna
end()
, allora non ha trovato nulla di interessante.
- In caso contrario,
it->first >= key
così ci liberiamo del caso >
(di alcun interesse per noi)
Vorrei sottolineare però che questo restituisce solo il primo elemento della gamma. Se siete interessati a tutti gli elementi, provare:
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));
}
Ciò restituirà l'intera gamma di nodi in s
il cui primo elemento è uguale a key
. È quindi solo necessario iterare su questa gamma:
for (Set::const_iterator it = range.first; it != range.second; ++it) {
// do something
}
E non hanno nemmeno bisogno di preoccuparsi se il ritorno di lower_bound
o upper_bound
era alla fine o meno.
- se
lower_bound
ritorni end()
, così fa upper_bound
, e il ciclo viene saltato
- se
lower_bound
indica un nodo per cui it->first > key
, poi upper_bound
indicheranno che stesso nodo, e il ciclo viene saltato
Questa è la potenza degli intervalli: non è necessario effettuare controlli speciali, gli intervalli finiscono vuoti quando non c'è corrispondenza, quindi il ciclo su di essi viene saltato in un unico controllo.
fonte
2012-03-23 20:18:58
Perché non stai usando una 'mappa'? Altre note: se è un 'std :: set', perché si chiama' myList'? Hai creato una funzione di confronto per 'std :: pair's? Com'è? –