Se ho capito bene, entrambe le chiavi std :: map e std :: unordered_map memorizzano esplicitamente (memorizzano coppie di chiavi/valori). Esiste un altro contenitore pronto per l'uso (std, boost o altra implementazione diffusa) che non memorizzerebbe la chiave, ma piuttosto consentirebbe di derivare la chiave dal valore memorizzato usando una funzione (vale a dire usare la chiave implicita?).std, boost o altra implementazione diffusa di un contenitore tabella hash con chiavi implicite
risposta
std::set
o std::unordered_set
, con funzioni di hash e/o confronto idonee per il tipo di valore memorizzato.
Tuttavia, la ricerca verrà eseguita dal tipo di valore memorizzato, non dalla chiave, quindi sarà necessario anche un modo per fabbricare un oggetto temporaneo da una chiave.
Tutti i contenitori ordinati nella libreria C++, ad es. std::set
consentire meno confronto tratto tratto, passarlo come un secondo parametro modello (my_less
nell'esempio seguente). . Se non lo fai, operator<
verrà cercato tramite ADL e usato se trovato (errore di compilazione se non); dovrebbe essere appropriato per molti casi.
Il proprio tratto o operator<
può essere utilizzato per definire l'ordine in base ai dati memorizzati in un set, cioè senza chiave. Nessun dato viene copiato per eseguire questo confronto, si prega di notare che ci vogliono riferimenti const.
Se non si desidera creare l'oggetto stack e preferisce utilizzare puntatori heap invece, ovviamente è possibile memorizzare boost::shared_ptr
in container standard ordinata e scrivere il meno rispetto tratto di conseguenza. In questo caso si può anche considerare l'utilizzo di boost ptr containers
Esempio:
#include <boost/shared_ptr.hpp>
#include <set>
#include <iterator>
#include <iostream>
struct order_by_AB { int a; int b; int c;
order_by_AB(int a, int b, int c) : a(a), b(b), c(c) {}
};
struct my_less
{
bool operator()(const boost::shared_ptr<order_by_AB>& lh, const boost::shared_ptr<order_by_AB>& rh)
{
if (lh->a == rh->a)
return lh->b < rh->b;
return lh->a < rh->a;
}
};
std::ostream& operator<< (std::ostream& os, const boost::shared_ptr<order_by_AB>& rh)
{
os << "(" << rh->a << "," << rh->b << "," << rh->c << ")";
return os;
}
int main()
{
std::set<boost::shared_ptr<order_by_AB>, my_less> data;
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(0, 1, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(2, 3, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(0, 3, 2)));
data.insert(boost::shared_ptr<order_by_AB>(new order_by_AB(2, 1, 2)));
std::copy(data.begin(), data.end(), std::ostream_iterator<boost::shared_ptr<order_by_AB>>(std::cout, "\n"));
return 0;
}
A cura a dare esempio di funtore specificato dall'utente per il confronto. A cura aggiungere boost::shared_ptr
in un contenitore
Come ho già detto in un'altra risposta, il problema con questo è che è necessario un oggetto completo per fare ricerche. Non puoi fare una ricerca con solo una chiave, come puoi con la mappa. –
Non capisco qualcosa. Da cosa vuoi ricavare la tua chiave e chi dovrebbe fare questa derivazione? Il codice sopra riportato deriva la chiave dal valore memorizzato. Questo può essere delegato se necessario, ad es. alla funzione membro di una classe memorizzata nel contenitore. Vuoi derivare la chiave senza effettivamente accedere al valore? In tal caso, dove verrebbero formati i dati necessari per ricavare il valore chiave? – bronekk
Puoi fare 'data [x]' dove 'x' non è un oggetto completo' order_by_AB'? Perché a volte può essere difficile trovare un oggetto completo: immagina se l'oggetto contenesse qualche risorsa. –
Si potrebbe essere alla ricerca di Boost.Intrusive. Spingi i contenitori intrusivi "agganciati" ai tuoi tipi di valore per fornire le caratteristiche di un determinato contenitore (ad es. Set, elenco, albero AVL, ecc.) Direttamente dagli oggetti.
Vedere Differences between intrusive and non-intrusive containers per una panoramica delle differenze tra contenitori STL e contenitori Boost Intrusive.
- 1. Treap con chiavi implicite
- 2. Inatteso imprevisto con std :: hash
- 3. Ricerca di una buona implementazione della tabella hash in C
- 4. Implementazione tabella/mappa hash senza allocazioni dinamiche
- 5. Inoltro perfetto e std :: tupla (o altra classe di modelli)
- 6. Sostituisci tabella vettoriale e hash con Boost.Bimap
- 7. Concatenate boost :: dynamic_bitset o std :: bitset
- 8. RSpec: confronto di un hash con chiavi stringa contro un hash con i tasti simbolo?
- 9. Creazione di una tabella hash/funzione hash
- 10. boost :: implementazione variante
- 11. std :: specializzazione hash con sfinae?
- 12. INSERT-OUTPUT con colonna da altra tabella
- 13. Boost ASIO IO_SERVICE Implementazione?
- 14. Un hash può avere chiavi o valori duplicati
- 15. Un DAO per classe 'contenitore' o un DAO per tabella?
- 16. Implementazione di un no-op std :: ostream
- 17. Utilizzo di boost :: tuple in tr1 :: hash
- 18. Come cambiare tutte le chiavi di un hash con un nuovo set di chiavi date
- 19. Coppie come chiavi hash
- 20. Boost multi-index container vs un contenitore di mappatura multi-livello basato su std :: unordered_map (mappa delle mappe)
- 21. Implementazione della gestione chiavi DUKPT
- 22. Come ottenere tabella con riferimenti altra tabella in yii2?
- 23. Ricerca tabella hash - con hash perfetto, in C
- 24. Puoi usare `std :: remove_if` su un contenitore di` std :: unique_ptr`?
- 25. Un contenitore std :: map che mappa i tipi ai valori
- 26. Implementazione Python di Jenkins Hash?
- 27. Implementazione C# di FNV Hash
- 28. Valore hash per una std :: unordered_map
- 29. Boost equivalente di std :: async()
- 30. boost :: ifind_first con std :: string objects
Questi consentono di eseguire ricerche * solo con una chiave *, anziché richiedere un oggetto completo? –
@ R.MartinhoFernandes: immagino di no; forse ho frainteso la domanda. Ma questo potrebbe essere un approccio ragionevole, purché si possa facilmente creare un oggetto temporaneo da una chiave. –
@ R.MartinhoFernandes che sarebbe (a mio avviso) una domanda/esigenza diversa. Fin dall'inizio, è possibile creare un oggetto parziale con le informazioni sufficienti per la generazione della chiave. Poi di nuovo nella maggior parte dei casi non estremi vorrei andare avanti e memorizzare la chiave comunque (la memoria è a buon mercato al giorno d'oggi) –