2012-10-10 14 views
6

Muszę zadeklarować tablicę tablic lub tablicy wielowymiarowej bez znajomości rozmiaru. chcę zrobić coś podobnego, że zrobić w tym przypadku prostych tablic:C++ zadeklaruj tablicę tablic bez znajomości rozmiaru

int *array; 
cin >> size; 
array = new int[size]; 

Może uda mi się zrobić pętlę zainicjować wskaźnik wskaźników takiego:

int **array; 
cin >> rows >> col; 
array = new *int[rows] 
for (int i = 0; i < rows; ++i) 
    array[i] = new int[col]; 

Ale wolę don nie rób tego, jeśli możliwe jest lepsze rozwiązanie.

+0

Jeśli chcesz tablicę o rozmiarze znany tylko w czasie wykonywania, co prawdopodobnie jest naprawdę chcesz 'std :: vector'. – cHao

+1

Czy dowiedziałeś się o standardowej bibliotece? Czy wiesz, co to jest 'std :: vector'? – amdn

+0

@PuraVida Znam doskonale standardową bibliotekę dzięki. Testuję wydajność przy użyciu wektora > i tablicy int [] [], więc potrzebuję użyć tablicy i dlatego nie chcę używać pętli do jej zainicjowania. –

Odpowiedz

5

Dlaczego nie używać std :: vector?

std::vector<std::vector<int> > array; 

Jeśli nie chcesz używać tablicę wskaźników, można użyć jedną dużą tablicę, która można przydzielić dynamicznie po Ci rozmiar i dostęp do niego jako tablicę wierszy.

int rows = 10; 
int columns = 20; 

int* array = new int[rows * columns]; 

for (int count = 0; count < rows; count++) 
{ 
    int* row = &array[count * columns]; 

    for (int inner_count = 0; inner_count < columns; inner_count++) 
    { 
     int* element = &row[inner_count]; 

     //do something 
    } 
} 

delete [] array; 
+2

Nie używaj wektora "wektorów", jeśli dany kod jest wrażliwy na wydajność. Staniesz twarzą w twarz z wieloma brakami w pamięci podręcznej w porównaniu do pojedynczego dużego bloku pamięci. –

+0

@ EdS.yea jest to jeden z powodów i chcę spróbować zrobić to bez użycia pętli, aby go zainicjować. –

1

Będziesz musiał przejść z wersją pętli. Można wykonać jedną lekką poprawę, która jest przeznaczyć jeden duży blok, a następnie zbudować swój własny indeks int* do niego:

int **array; 
int *storage; 
cin >> rows >> col; 
array = new *int[rows]; 
storage = new int[rows*col]; 
for (int i = 0; i < rows; ++i) 
    array[i] = storage + col * i; 

Ma to ładny obiekt, który można nadal korzystać array[i][j] składnię dla dostępu do tablicy.

0

Jeśli zależy, można mieć trochę większą wygodę przez mieć pomocnika

template <typename T> 
struct C3DArray 
{ 
    vector<vector<vector<T>>> m; 
    C3DArray(int size_x, int size_y, int size_z) 
     : m(make(T(), size_z, size_y, size_x)) 
    { } 

    template <typename U> static std::vector<U> make(U v, size_t n) { 
     return { n, std::move(v) }; 
    } 

    template <typename U, typename... Dim> static auto make(U v, size_t n, Dim... other) 
     -> std::vector<decltype(make(v, other...))> { 
     return { n, make(v, other...) }; 
    } 
}; 

używa variadics. Używaj go tak:

C3DArray<int> arr(3,4,20); 
0

Można używać jednego std :: vector zawiera całą tablicę dwuwymiarową i owinąć go w klasie, aby ukryć szczegóły. Oto przykład, używa funkcji składowej data(row, col), która zwraca odniesienie do elementu pod row i col. Włączyłem przykładową dwuwymiarową macierz z int, gdzie każdy wpis w tablicy jest inicjowany na produkt jego row i col. Gdy instancja tej klasy wykracza poza zakres, domyślny destruktor zostanie wywołany i zwolni pamięć, dzięki czemu nie musisz pamiętać, aby wywołać delete [] w celu zwolnienia pamięci. Wszystkie elementy macierzy będą przylegać do pamięci, jest to pamięć podręczna przyjazna i powinna zapewnić dobrą wydajność.

#include <iostream> 
#include <vector> 
#include <stdexcept> 

template <typename T> 
class matrix { 
    std::vector<T> data_; 
public: 
    size_t const rows_; 
    size_t const cols_; 
    matrix(size_t rows, size_t cols) 
     : rows_(rows) 
     , cols_(cols) 
     , data_(rows * cols) 
    {} 
    T& data(size_t row, size_t col) { 
     if (row > rows_ || col > cols_) throw std::out_of_range("matrix"); 
     return data_[ row * cols_ + col ]; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    matrix<int> array(100,100); 

    for(size_t r=0; r < array.rows_; ++r) { 
     for(size_t c=0; c < array.cols_; ++c) { 
      array.data(r,c) = r * c; 
     } 
    } 

    std::cout << "8 x 7 = " << array.data(8,7) << std::endl; 

    return 0; // array goes out of scope here, memory released automatically 
} 

Po uruchomieniu tego dostaniesz

8 x 7 = 56 
+0

dzięki za wyjaśnienie, spróbuję tego –

Powiązane problemy