2009-03-30 5 views
6

Ho una matrice di stringhe piena di parole da una frase.Ho bisogno di avere una chiave con più valori. Quale infrastruttura ti raccomanderebbe?

parole [0] = "i"
parole [1] = "cane"
parole [2] = "saltato"
parole [3] = "over"
parole [4] = " "
words [5] =" wall ".
parole [6] = "i"
parole [7] = "cat"
parole [8] = "caduto"
parole [9] = "off"
parole [10] = "il"
parole [10] = "casa".
ecc (ad esempio stupido, ma funziona per questo)

Ogni parola sarà una chiave con la sua parola seguente come valore. quindi "sopra" => "il". Alcuni tasti possono avere più valori. Ad esempio, "il" => "cane" || "muro" || "gatto" || "Casa". Il valore è scelto casualmente da quelli per quella chiave.

Quando il programma viene eseguito, seleziona una parola a caso e pronuncia una frase. Quindi potrebbe essere qualcosa come: "il gatto è caduto dal cane".

Ho provato a implementare una mappa (mappa myMap;) ma ciò consente solo un valore per chiave (credo).

Spero di aver spiegato bene.

risposta

4

è possibile utilizzare un multimap dal STL e utilizzare la chiamata

pair<iterator, iterator> equal_range(const key_type& k) 

per ottenere una gamma di iteratori che corrispondono alla vostra chiave

Personalmente trovo questo un po 'goffo a causa di avere a che fare con iteratore varia piuttosto che ottenere indietro un oggetto che rappresenta tutti i valori per quella chiave. per aggirare il fatto che è possibile anche memorizzare un vettore in una mappa regolare e aggiungere le stringhe al vettore.

24

std::multimap

Il collegamento fornisce un esempio eccellente. Citato di seguito:

int main() 
{ 
    multimap<const char*, int, ltstr> m; 

    m.insert(pair<const char* const, int>("a", 1)); 
    m.insert(pair<const char* const, int>("c", 2)); 
    m.insert(pair<const char* const, int>("b", 3)); 
    m.insert(pair<const char* const, int>("b", 4)); 
    m.insert(pair<const char* const, int>("a", 5)); 
    m.insert(pair<const char* const, int>("b", 6)); 

    cout << "Number of elements with key a: " << m.count("a") << endl; 
    cout << "Number of elements with key b: " << m.count("b") << endl; 
    cout << "Number of elements with key c: " << m.count("c") << endl; 

    cout << "Elements in m: " << endl; 
    for (multimap<const char*, int, ltstr>::iterator it = m.begin(); 
     it != m.end(); 
     ++it) 
    cout << " [" << (*it).first << ", " << (*it).second << "]" << endl; 
} 
+0

Grazie per la risposta rapida. Quando si utilizza una mappa, posso accedere ai valori utilizzando la mappa [chiave]. Come posso ottenere i valori usando un multimap? –

+1

@Haawk: multimap ha un metodo chiamato equal_range() che restituisce una coppia di iteratori che indicano l'intervallo di elementi uguale a una determinata chiave. –

0

Come altri due hanno sottolineato, std :: multimap può essere la soluzione.

Considerare anche std::tr1::unordered_multimap. È disponibile in VS 2008 sembra averlo, GCC lo ha almeno dalla versione 4.3.

4

Se stai usando C++ poi basta creare una classe per rappresentare le vostre coppie chiave-valore:

Class foo { 
    key : String 
    values : list of values 
} 

Quindi, creare una mappa che associa ogni chiave ad un oggetto che contiene i suoi valori.

Questo è semplice, estensibile e può essere eseguito in qualsiasi linguaggio OO.

Spiacente, il mio C++ è arrugginito quindi la sintassi è errata, ma l'idea essenziale è semplice.

0

È inoltre possibile utilizzare unordered_map> che presenta alcuni vantaggi rispetto alla struttura della mappa. Si può fare tale inserimento, se il dizionario è come 'c': "cat", 'c': "auto", 'a': mela, 'a': "Angus":

unordered_map<char, vector<string>> char_to_strings_map; 
//loop to traverse the dictionary : key:c, value:s 
    char_to_strings_map[c].emplace_back(s); 
//loop ends 
0

Non ci può essere un approccio alternativo per ottenere due valori per chiave, specialmente per i casi in cui la maggior parte degli elementi della mappa ha due valori per chiave. Associando due valori per una chiave, come accennato in questo link:

std::map<std::string, std::pair<std::int, int> > myMap2 

utilizzarlo nella funzione come:

#include<iostream> 
#include<map> 
#include<iterator> 
using namespace std; 
int main(){ 
map<string,pair<int,int>>mp; 
mp.insert(pair<string,pair<int,int>>("ab",make_pair(50,7))); 
mp.insert(pair<string,pair<int,int>>("cd",make_pair(51,8))); 
map<string,pair<int,int>>::iterator it; 
for(it=mp.begin();it!=mp.end();it++) 
    cout<<it->first<<" "<<it->second.first<<" "<<it->second.second<<" "; 
return 0; 
} 
0

Ho scoperto che una struttura può funzionare bene per questa situazione. Questo approccio (fondamentalmente simile a una classe) consente un accesso più pulito ai parametri definiti come meglio credi.

struct car_parts { 

    string wheelType; 
    string engine; 
    int number_of_cylinders; 

    car_parts(string _wheelType, string _engine, int _number_of_cylinders) 
    { 
     wheelType = _wheelType; 
     engine = _engine; 
     number_of_cylinders = _number_of_cylinders; 
    } 
}; 

int main() 
{ 
    // Populate the dictionary 
    map<char, car_parts> vehicles = 
    { 
     { 'I', car_parts("All terrain", "X2", 6) }, 
     { 'C', car_parts("Summer only", "BB", 8) }, 
     { 'U', car_parts("All terrain", "X3", 4) } 
    }; 

    map<char, car_parts>::iterator it; 

    it = vehicles.find('I'); 

    if (it != vehicles.end()) 
    { 
     cout << "The vehicle with key of I has " << it->second.number_of_cylinders << " cylinders\n"; 
    } 
} 
Problemi correlati