2016-11-02 73 views
5

muszę strukturę następująco:Która struktura danych jest lepsze dla tablicy std ciąg

Figure1

Konstrukcja musi posiada stały rozmiar std::string s, a liczba jej elementów jest finit (100 - 10000000).

Jedynym wymogiem, który muszę to możliwość dostępu do każdego elementu losowo następujące:

std::string Temp = MyStrcuture[i]; 

lub

MyStrcuture[i] = std::string Temp; 

muszę wybrać najszybszą strukturę z NO (ewentualnie) wyciek pamięci .

Który z nich jest lepszy dla mnie?

  1. std::string* MyStrcuture = new std::string[Nu_of_Elements];
  2. std::queue< std:string> MyStrcuture(Nu_of_Elements);
  3. std::vector< std:string> MyStrcuture(Nu_of_Elements);
  4. boost::circular_buffer< std::string> MyStrcuture(Nu_of_Elements);
  5. Twoja sugestia?
+0

Czy kolejka jest nawet losowo dostępna? –

+0

Co więcej, czy C++ ma tabelę skrótów? To może być miłe. –

+0

unordered_map zbliża się do hashtable w C++ –

Odpowiedz

12
std::vector< std:string> MyStrcuture(Nu_of_Elements); 

Vector jest najlepiej pasuje do Twoich wymagań. Obsługuje dostęp do elementów opartych na indeksach, ponieważ elementy są przechowywane w ciągłych adresach pamięci i mają elastyczność pod względem wielkości.


  1. std: string * MyStrcuture = new std :: string [Nu_of_Elements]; nr

    C++ STL vector vs array in the real world

  2. std :: kolejka < std: string> MyStrcuture (Nu_of_Elements); nr

    How do I get the nth item in a queue in java?
    Index oparte dostęp element nie jest obsługiwany.

  3. std :: wektor < std: string> MyStrcuture (Nu_of_Elements); Tak

    Clean-up: destruktor wektora automatycznie wywołuje destruktor każdego elementu w wektorze.

  4. Zwiększenie :: cykliczny bufor < std :: string> MyStrcuture (Nu_of_Elements); Nie

    Powód taki sam jak drugi.Know more

+2

Zamiast 'std :: vector ', 'std :: vector >' ma więcej sensu z perspektywy pamięci. – themagicalyang

+1

@themagicalyang: tak i nie, ponieważ wymagałoby dużego bloku ciągłej pamięci, która może nie być dostępna w np. pofragmentowana 32-bitowa przestrzeń adresowa. –

+0

@MatteoItalia Zgadzam się. Ale jeśli tak jest, należy sprawdzić, czy przydział jest nieprawidłowy. Ale ciągła pamięć pamięci nadal byłaby moim pierwszym wyborem. Jeśli nie powrócisz, na innym schemacie alokacji. – themagicalyang

4

Cóż, ponieważ ciąg mają stałą wielkość, jeśli nie posiada dedykowanego wymóg podczas przetwarzania ciąg i mają wystarczająco dużo wolnej pamięci do przyległej alokacji. Możesz użyć std :: array < char, 400> lub std :: unique_ptr < char *> zamiast std :: string.

  1. Musisz zarządzać pamięcią w sposób C. rozważyć inteligentny wskaznik
  2. std :: kolejka nie ma swobodnego dostępu, Access c++ queue elements like an array

  3. std :: vector jest odpowiedni, jeśli liczba ciąg zostanie zmieniona. Jednak funkcja clear() po prostu wywołuje destruktor elementów, a nie wektor wolnej pamięci (można sprawdzić pojemność po wyczyszczeniu).

  4. Po przeczytaniu boost documentation. Bufor cykliczny z dostępem swobodnym jest odpowiedni, jeśli twój numer łańcucha ma górny limit (który powiedziałeś 10 milionów). Ale to marnowanie pamięci, jeśli w rzeczywistości masz tak mało strun. Sugeruję więc użycie z inteligentnym wskaźnikiem.

  5. Jeśli twój numer ciągu jest stały i niezmieniony od początku. Można spojrzeć na C++11 array container

0

Jeśli ilość elementów i długość jest stała i pamięć jest krytyczna, można rozważyć użycie zwykłego tablicy char, która zapewnia minimalny pamięci napowietrznych i szybki dostęp. Twój kod będzie wyglądać tak:

char* MyStructure = new char[n * 401]; 
memset(MyStructure, 0, n * 401); 

std::string Temp = MyStructure[i * 401]; // Get value 
strcpy(MyStructure[i * 401], Temp.c_str()); // Put value 

401 tutaj jest dla 400 bajtów ciągu i 1 końcowego zera.

+2

To jest właściwe rozwiązanie. Dlaczego warto wybrać dynamicznie przydzielony std :: string, gdy łańcuchy mają stały rozmiar i mogą być przechowywane w tablicy znaków. Dodatkową korzyścią jest szybki dostęp i brak przeskoków pamięci. Chociaż zamiast tego użyłbym 'std :: array '. Tak więc może to być 'std :: vector ' – themagicalyang

+1

Jestem pewny, że masz na myśli * końcowe * *. – celtschk

+0

"1 wiodące zero"? Czy miałeś na myśli zerową terminację? –