2012-12-24 12 views
5

dire che ho un vettore come questo:C++ in uno std :: vector

vector< pair<string, pair<int, int> > > cont; 

Ora voglio nel cont trovare l'elem che ha il suo first pari a "ABC". Come posso farlo facilmente con i funtori e gli algoritmi che STL ci fornisce (find_if, is_equal ??). (No Amplificato per favore e nessun nuovo C++.)

EDIT: E 'possibile fare a meno di definire un funtore predicato?

+1

L'hai detto tu stesso: 'std :: find_if'. Puoi combinarlo anche con un lambda. – chris

+0

Perché l'odio per C++ 11? – nikhil

+0

Nessun odio, lo adoriamo! :) – Narek

risposta

7

Qualcosa di simile

typedef std::pair<std::string, std::pair<int, int> > pair_t; 

struct Predicate : public std::unary_function<pair_t, bool> 
{ 
public: 
    Predicate(const std::string& s):value(s) { } 
    result_type operator() (const argument_type& pair) 
    { 
     return pair.first == value; 
    } 
private: 
    std::string value; 
}; 

std::vector<pair_t>::const_iterator pos = std::find_if(cont.begin(), cont.end(), 
Predicate("ABC")); 

o lambda, se C++ 11.

auto pos = std::find_if(cont.begin(), cont.end(), 
[](const std::pair<std::string, std::pair<int, int>>& pair) 
{ 
    return pair.first == "ABC"; 
}); 

davvero, c'è un modo non buono per fare una cosa del genere, senza struttura.

typedef std::pair<std::string, std::pair<int, int> > pair_t; 

namespace std { 
template<> 
bool operator ==<> (const pair_t& first, const pair_t& second) 
{ 
    return first.first == second.first; 
} 
} 

std::vector<pair_t>::const_iterator pos = std::find_if(cont.begin(), cont.end(), 
std::bind2nd(std::equal_to<pair_t>(), std::make_pair("ABC", std::make_pair(1, 2)))); 
+0

Con lo standard più vecchio per favore? – Narek

+0

Grazie per le buone soluzioni. È possibile fare lo stesso senza definire un Predicato? – Narek

+0

@ Narek, sì, con la stringa hardcode "ABC". – ForEveR

1

Se avete bisogno di più veloce di O(N) di ricerca, è possibile sostituire vector con map (o aggiungere in parallelo) per O(log N) di ricerca (o O(1) con unordered_map), non è necessaria alcuna funtore:

vector<pair<string, pair<int,int>>> cont {{"ABC",{1,11}}, {"DFG",{2,22}}}; 
map  <string, pair<int,int>> M(cont.begin(), cont.end()); 
cout << M["ABC"] << endl; 

E usando RO library (spina vergognosa), questo sarà solo:

#include <sto/sto.h> 
using namespace sto; 

... 
auto it = cont/(_0=="ABC"); 

Qui op. / sovraccarico che internamente chiama find_if; _0 - riferimento al primo elemento di tupla (o coppia) nell'espressione lambda STO; _0=="ABC" - espressione lambda che genera predicato per find_if

+0

strutture di dati non ordinate rischiano di essere più lente di ordinati strutture dati, dipende, d'altra parte, un vettore e la sua concessione per un'allocazione contigua in memoria possono, a volte, essere davvero exp ensive. – user1849534