2009-04-30 10 views
5

Duplicate:Choosing a STL container with uniqueness and which keeps insertion orderingEsiste una struttura dati che non consente duplicati e mantiene anche l'ordine di immissione?

Sto cercando una struttura di dati che si comporta come un insieme, in quanto non consente duplicati da inserire, ma sa anche l'ordine in cui sono stati inseriti gli articoli. Sarebbe fondamentalmente una combinazione di un set e di un elenco/vettore.

Vorrei solo utilizzare un elenco/vettore e verificare personalmente i duplicati, ma è necessario che tale verifica duplicata sia veloce poiché le dimensioni della struttura possono diventare piuttosto grandi.

risposta

6

Dai uno sguardo allo Boost.MultiIndex. Potrebbe essere necessario scrivere un wrapper su questo.

+0

La soluzione di Greg nella domanda duplicata non sembra richiedere il wrapper. Grazie per avermi indicato nella direzione più indolore, però. –

1

Scrivere la propria classe che racchiude un vettore e un set sembrerebbe la soluzione più ovvia - non esiste un contenitore di libreria standard C++ che faccia ciò che si desidera.

0

Vorrei utilizzare solo due strutture dati, una per l'ordine e una per l'identità. (Si potrebbe indicare nell'altro se si memorizzano valori, a seconda dell'operazione che si desidera più veloce)

0

La verifica di duplicati che è veloce sembra essere la parte critica qui. Potrei usare un tipo di mappa/dizionario e tenere traccia dell'ordine di inserimento come dati effettivi. Quindi la chiave sono i "dati" in cui ti stai spingendo (che viene quindi sottoposto a hash, e non permetti chiavi duplicate), e inserisci la dimensione corrente della mappa come "dati". Ovviamente questo funziona solo se non si hanno cancellazioni. Se è necessario, basta avere una variabile esterna che si incrementa ad ogni inserimento, e l'ordine relativo ti dirà quando le cose sono state inserite.

Non necessariamente bello, ma non così difficile da implementare.

2

A Boost.Bimap con l'ordine di inserimento come dovrebbe funzionare un indice (ad esempio boost :: bimap < size_t, Foo>). Se si rimuovono oggetti dalla struttura dati, sarà necessario monitorare separatamente il successivo valore dell'ordine di inserimento.

0

Supponendo che si stia parlando ANSI C++, scriverei il mio o utilizzare composizione e delega per racchiudere una mappa per l'archiviazione dei dati e un vettore delle chiavi per l'ordine di inserimento. A seconda delle caratteristiche dei dati, potresti essere in grado di utilizzare l'indice di inserimento come chiave della mappa ed evitare di utilizzare il vettore.

0

Java ha questo sotto forma di un set ordinato. Non ho nulla in C++, ma non è così difficile da implementare. Quello che i ragazzi del Sun hanno fatto con la classe Java è stato quello di estendere la tabella hash in modo tale che ogni elemento fosse contemporaneamente inserito in una tabella hash e conservato in un doppio elenco collegato. Ci sono pochissime spese generali in questo, specialmente se si preallocano gli elementi utilizzati per costruire l'elenco collegato.

Se io dovessi scrivere una classe che utilizzava un vettore privato per archiviare gli elementi o implementare un hashtable nella classe. Quando un elemento deve essere inserito nel set, controlla se è nella tabella hash e se lo sostituisci, opzionalmente sostituiscilo. Quindi trova il vecchio elemento nella tabella hash, aggiorna l'elenco in modo che punti al nuovo elemento e il gioco è fatto.

Per inserire un nuovo elemento si fa lo stesso, tranne che è necessario utilizzare un nuovo elemento nell'elenco - non è possibile riutilizzare quelli vecchi.

Per eliminare un elemento, si riordina l'elenco in modo che punti intorno ad esso e liberi l'elemento dell'elenco.

Nota che dovrebbe essere possibile ottenere la parte dell'elenco collegato in cui l'elemento che ti interessa è direttamente dall'elemento in modo da non dover camminare sulla catena ogni volta che devi spostarti o cambia un elemento.

Se si prevede di avere molti di questi articoli modificati durante l'esecuzione del programma, è possibile mantenere un elenco degli elementi dell'elenco, in modo tale che si possa semplicemente assumere la testa di questo elenco, anziché allocare memoria ogni volta che si devo aggiungere un nuovo elemento.

Si potrebbe voler osservare l'algoritmo dei collegamenti di danza.

Problemi correlati