C'è un modo di iterare su un (possibilmente enorme) std::bitset
ovvero lineare nel numero di bit impostato su true? Voglio evitare di dover controllare ogni singola posizione nel bitset. L'iterazione dovrebbe successivamente restituire gli indici di ciascun bit impostato su true.Modo efficiente di iterare su bit true in std :: bitset?
risposta
Affinché ciò sia lineare, è necessario un elenco/matrice/set di indici impostati true. Mantenere un tale indice secondario non fa parte dei compromessi prestazionali/di archiviazione richiesti da std :: bitset, e dato che svantaggerebbe tutti senza il tuo specifico requisito, non c'è modo che un'implementazione fornisca questo. Potresti considerare di integrare il tuo set di bit con un contenitore di questo tipo, oppure utilizzare la libreria di contenitori multiindice di boost.
In loop su tutto il set di bit e semplicemente controllando il valore e memorizzando l'indice se vero, IS linear. Puoi accelerarlo con una tabella di ricerca. Vedere questo codice:
Il punto della domanda era che la scansione dell'intero set di bit non è necessariamente lineare rispetto al numero di bit impostati. Ad esempio, se il numero di set di bit fosse noto come ~ ln N dove N era la dimensione del set, allora una scansione prenderà comunque O (N) e non O (ln N). –
Eddie, non è lineare nel numero di bit reali. Ti preghiamo di considerare di modificare la tua risposta o di rimuoverla. – einpoklum
È possibile controllare fino a 32-bit alla volta con un accumulatore U64 e un tavolo da 32-entry come
u32 kTable[]
{
0x01, 0x03, 0x07, 0x0F ..., 0xFFFFFFFF
};
Basta leggere a 32 bit in un U64 accumulatore e spostarlo verso il basso a seconda dell'offset e controllare i bit contro il tavolo. È possibile farlo in modo binario per ottenere il numero di confronti a un massimo di 5. Ciò sarà più lento per i dati che non sono "lineari" nella moda. Questo diventa quindi il tempo di registrazione.
Un bitvector standard non supporta un'iterazione efficiente su bit reali - il runtime è sempre O (n), dove n è il numero di bit totali, che non dipende da k. Tuttavia, una struttura speciale chiamata van Emde Boas Tree supporta l'iterazione sui bit nel tempo O (k lg lg n), dove n è il numero di bit e k è il numero di bit reali.
Come un po 'di spudorato auto-promozione, ho an implementation of a vEB-tree on my personal website. Se è inappropriato per me pubblicizzarlo qui, per favore fammelo sapere e lo prenderò in considerazione.
ci sono solo due opzioni che fare molto meglio di O (N) sui bit totale:
- l'uso delle istruzioni specialità bit di scansione disponibili in alcune architetture come BSF in x86.
- Esistono algoritmi O (log2 (N)) per trovare il bit più basso impostato in una parola. Questo, naturalmente, non si adatta bene quando il bitset è denso, piuttosto che scarso. Resuscitando un mio nebbioso ricordo, ho trovato la fonte nei dettagli FXT library nella FXT book (pdf), nella sezione 1.3.2.
A volte le persone usano run-length encoding per cose del genere. Se si codifica il bitset in entrata in una serie di lunghezze di esecuzione, il numero di esecuzioni che si finisce non supera il numero di transizioni tra bit impostato e chiaro, che è al massimo 2*k
. Inoltre, in molte applicazioni il numero di transizioni è molto inferiore a k
, quindi si otterrà un'eccellente prestazione media in aggiunta a quella lineare peggiore.
Inoltre, è semplice aggiungere una struttura dati che consenta di cercare in modo efficiente cose come "il prossimo bit impostato a partire da n
th posizione nell'array": basta creare un scan di lunghezze di esecuzione.
- 1. Bit field vs Bitset
- 2. XOR bitset a 128 bit
- 3. Perché lo std :: swap di bit in un'istanza di std :: bitset non funziona?
- 4. modo efficiente per iterare throught elementi XML
- 5. Modo Pythonic per iterare su bit dell'intero numero
- 6. Come scrivere un template std :: bitset che funziona su 32 e 64-bit
- 7. Concatenate boost :: dynamic_bitset o std :: bitset
- 8. C'è un modo banale per ottenere complemento a 2 di uno std :: bitset <N>
- 9. Come iterare std :: set?
- 10. Perché std :: bitset :: size non statico
- 11. Matrice di bit efficiente C/C++
- 12. Rimuovere in modo efficiente l'ultimo elemento da std :: list
- 13. Come implementare un vettore bit (bitset) (in Java)?
- 14. Inizializza in modo casuale BitSet in JAVA
- 15. Modo orientato agli oggetti per iterare attraverso un vettore std ::?
- 16. Come posso mischiare i bit in modo efficiente?
- 17. confrontare in modo efficiente QString e std :: string per l'uguaglianza
- 18. Perl modo di iterare su 2 campi in parallelo
- 19. efficiente passaggio di std :: vector
- 20. Costrutto bitset da array di interi
- 21. Mappa non ordinata (hash) da bitset a bitset su boost
- 22. BitSet Java che consente una facile concatenazione di BitSet
- 23. booleano [] rispetto a BitSet: che è più efficiente?
- 24. Come convertire un sottoinsieme di intervalli di bit in un set di bit C++ in un numero?
- 25. Come iterare una relazione NSSet (Objective-C) - To-Many in Core Data - in modo efficiente?
- 26. utilizzando contenitore bitset in C++
- 27. Modo Pythonic per iterare su un'istanza collections.Counter() in ordine decrescente?
- 28. Salvataggio di BitSet java su DB
- 29. iterare su tutte le coppie di elementi in STD-contenitori (C++)
- 30. BitSet mutabile Scala, dove sono le operazioni di muting?
È inoltre possibile trovare il codice per bitset sparse sul Web. – etarion
Capisco. Sfortunatamente, mantenere una memoria separata degli indici non è un'opzione. Grazie per i tuoi approfondimenti. – Astyanax