2010-07-12 1 views
9

Diciamo che ho una collezione di oggetti Person, ognuno dei quali si presenta così:Quale contenitore STL per i dati ordinati con accesso basato su chiave?

class Person 
{ 
    string Name; 
    string UniqueID; 
} 

Ora, gli oggetti devono essere conservati in un contenitore che mi permette di ordinare in modo che io possa determinato elemento X facilmente individuare l'elemento X + 1 e X-1.

Tuttavia, ho anche bisogno di un accesso rapido basato su UniqueID, in quanto la raccolta sarà ampia e una ricerca lineare non la taglierà.

La mia "soluzione" corrente consiste nell'utilizzare una lista std :: in combinazione con una std :: map. L'elenco contiene le persone (per l'accesso ordinato) e la mappa viene utilizzata per associare UniqueID a un riferimento all'elemento dell'elenco. L'aggiornamento del "contenitore" in genere comporta l'aggiornamento sia della mappa che dell'elenco.

Funziona, ma credo che ci dovrebbe essere un modo più intelligente di farlo, forse boost:bimap. Suggerimenti?

MODIFICA: C'è una certa confusione circa il mio requisito per "ordinare". Per spiegare, gli oggetti vengono trasmessi in sequenza da un file e l''ordine' degli elementi nel contenitore deve corrispondere all'ordine dei file. L'ordine non è correlato agli ID.

+1

Cosa intendi per 'X + 1' e' X-1'? Ho la sensazione che non si riferisca al campo 'UniqueID', quindi che cos'è? A quale ordine ti riferisci? –

+0

Mi riferisco all'ordinamento all'interno del contenitore. cioè (presupponendo un vettore) Array [X], [X-1] e [X + 1] – Roddy

+1

Qual è l'ordine nel contenitore? Penso che sia quello che Matthieu sta cercando di definire. – Joel

risposta

8

boost:bimap è la scelta più ovvia. bimap è basato su boost::multi_index, ma bimap ha una sintassi semplificata. Personalmente preferirò boost::multi_index su boost::bimap perché consentirà di aggiungere facilmente più indici alla struttura Person in futuro.

+0

A proposito, domanda ai madrelingua: 'indices' o' indexes'? –

+3

'Indici' è il sostantivo plurale tecnicamente corretto.Ma chiunque capirà gli indici '... – Roddy

+0

Grazie. frustratamente ho scoperto che la mia toolchain (C++ Builder 2010) non supporta boost :: multi_index o bimap, ma hey, almeno io so cosa dovrei * usare *. – Roddy

7

Non esiste un contenitore di libreria standard che faccia ciò che si desidera, quindi sarà necessario utilizzare due contenitori o la soluzione Boost. Se si utilizzano due contenitori, normalmente preferirei un vettore o un deque su una lista, in quasi tutte le circostanze.

+0

@Neil, grazie. L'uso di un vettore significherebbe che l'eliminazione o l'inserimento di un elemento potenzialmente invaliderebbe TUTTI i riferimenti nella mia mappa. Quindi la lista. – Roddy

+0

@Roddy: non sono sicuro delle tue esigenze, ma ho un'idea che tu usi la tua lista come una coda. Se ho torto, per favore, sentiti libero di correggermi, ma se ho ragione, allora la soluzione di "deque" di Neil ha senso. –

+0

@Matthieu, Purtroppo no: ho ancora bisogno di inserimento/eliminazione casuale che non invalidi le posizioni di tutti gli altri elementi. – Roddy

1

Perché non utilizzare due mappe, una con Persona come Chiave e un'altra con UniqueId come Chiave, ma che richiede l'aggiornamento di entrambi.

è possibile creare una funzione di richiamata che aggiorna entrambe le mappe ogni volta che si verifica un cambiamento.

+0

"puoi creare una funzione di callback ..." Ah - come posso farlo ?? – Roddy

+2

Reinventando il Bimap :) –