2010-09-20 6 views
5

So che un vettore int semplice ha O (1) tempo di accesso casuale, poiché è facile calcolare la posizione dell'elemento xth, dato che tutti gli elementi hanno la stessa dimensione.C++: come funziona il tempo di accesso casuale dei vettori di stringa?

Ora che succede con un vettore di stringa?

Poiché le lunghezze delle stringhe variano, non può avere O (1) tempo di accesso casuale, vero? Se può, qual è la logica dietro?

Grazie.

Aggiornamento:

Le risposte sono molto chiaro e conciso, grazie a tutti per l'aiuto. Ho accettato la risposta di Joey perché è semplice e facile da capire.

+5

Una stringa e il suo contenuto non sono la stessa cosa. La dimensione di un oggetto è sempre costante. – GManNickG

risposta

12

Il vettore ha O (1) tempo di accesso.

Gli oggetti stringa hanno tutte le stesse dimensioni (in una determinata implementazione), indipendentemente dalla dimensione della stringa che rappresentano. In genere l'oggetto stringa contiene un puntatore alla memoria allocata che contiene i dati della stringa.

Quindi, se s è un std::string, quindi sizeof s è costante e pari a sizeof(std::string), ma s.size() dipende dal valore di stringa. Il vettore si occupa solo di sizeof(std::string).

+0

+1 Mi piace la distinzione tra 'size' e' sizeof'! – fredoverflow

+0

@FredOverflow: grazie. Ho riletto la mia risposta e ho capito che potrei essere un * lotto * più chiaro di cosa intendo per "la dimensione dell'oggetto stringa" e "la dimensione della stringa che rappresenta" :-) –

4

Poiché l'oggetto stringa ha una dimensione fissa proprio come qualsiasi altro tipo. La differenza è che l'oggetto stringa memorizza la propria stringa sull'heap e mantiene un puntatore alla stringa a dimensione fissa.

+2

Con l'ottimizzazione delle stringhe piccole potrebbe anche essere memorizzato direttamente nell'istanza della stringa. –

2

La stringa effettiva in una stringa: std :: di solito è solo un puntatore. La dimensione di una stringa è sempre la stessa, anche se la lunghezza della stringa che contiene varia.

+0

Erm ..di solito è un po 'più grande di un puntatore (di solito c'è un contatore per la dimensione della stringa e almeno la dimensione del blocco di memoria allocato). Ma ancora non le dimensioni della stringa stessa. –

+0

Sì, intendevo il contenuto effettivo dei dati, potrebbero esserci altri – nos

2

Hai ottenuto un numero di risposte (ad es., Steve Jessop e AraK) che sono per lo più corrette già. Aggiungerò solo un piccolo dettaglio: molte implementazioni correnti di std::string usano quello che viene chiamato ottimizzazione della stringa corta (SSO), il che significa che allocano una piccola quantità di spazio fisso nell'oggetto stringa stesso che può essere utilizzato per memorizzare stringhe corte e solo quando/se la lunghezza supera ciò che è allocato nell'oggetto stringa stesso, alloca effettivamente lo spazio separato sull'heap per archiviare i dati.

Per quanto riguarda un vettore di stringhe, questo non fa alcuna differenza: ogni oggetto stringa ha una dimensione fissa indipendentemente dalla lunghezza della stringa stessa. La differenza è che con SSO la dimensione fissa è maggiore e in molti casi l'oggetto stringa non ha blocco sull'archivio per contenere i dati effettivi.

+0

Sei sicuro che libstdC++ sia tra "molte implementazioni correnti"? – sellibitze

+0

@sellibitze: Offhand, non ricordo. Ho visto almeno una libreria per g ++ che ce l'ha e un'altra no, ma non ricordo quale sia stata ... –

+0

La versione di std :: string di GNU ha dimensione 4 (sulla mia macchina). È solo un puntatore in un blob assegnato, che contiene tutti i metadati e i dati di stringa. Tipo di opposto dell'ottimizzazione della stringa corta. –

5

I riferimenti di stringa sono memorizzati in un'unica posizione. Le stringhe possono essere memorizzate ovunque nella memoria. Quindi, hai ancora O (1) tempo di accesso casuale.

--------------------------- 
| 4000 | 4200 | 5000 | 6300 | <- data 
--------------------------- 
[1000] [1004] [1008] [1012] <- address 


[4000] [4200] [5000]  [6300]  <- starting address 
"string1" "string2" "string3" "string4" <- string 
+3

Molto bella rappresentazione visiva! –