• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Rozszerzanie dynamicznej tablicy (wielowymiarowej) o statyczne tablice

Object Storage Arubacloud
0 głosów
633 wizyt
pytanie zadane 31 marca 2016 w C i C++ przez ScriptyChris Mędrzec (190,190 p.)

Problem jest prosty, ale w momencie, gdy nie zna się języka, to jest irytujący :)

Chcę z funkcji zwracać tablicę (statyczna, 3 elementowa) i umieszczać ją w tablicy dynamicznej (czyli rozszerzać ją o kolejne tablice statyczne). Nie mogę podać rozmiaru tej dynamicznej tablicy przy jej inicjalizacji, bo go nie znam.

W JavaScript wyglądało by to w poniższy sposób (starałem się bardzo uprościć kod, bo w rzeczywistości dane x, y, z pochodzą z palety kolorów RGB i za każdym wywołaniem funkcji giveMeArray() są inne). Słabo znam C++. Zatem jak przepisać poniższy kod JavaScript na C++, aby to działało? (w przykładzie, do funkcji podaje parametry randomowe - w rzeczywistości lecą tam tylko inty, które pochodzą z palety kolorów RGB)

var x = 23,       // przykladowe wartosci - bo za kazdym razem sa inne, ale zawsze typu INT
     y = 34,
     z = 45;

var dynamicArray = []; // tablica o nieznanym rozmiarze poczatkowym, jesli to mozliwe w C++

function giveMeArray(a, b, c)
{
     var staticArr = []; // tablica zawsze 3 elementowa

     staticArr[0] = a;
     staticArr[1] = b;
     staticArr[2] = c;

    return staticArray;    // tablica po "pierwszym" zapelnieniu: staticArray = [23, 34, 45];
}

dynamicArray.push( giveMeArray(x, y, z) ); // przy kolejnych wywolaniach funkcji, zmienne x,y,z beda mialy inne wartosci, ale zawsze typu INT

// Wynik: dynamicArray =  [ staticArray1, staticArray2, ... , staticArrayN ];

Funkcja giveMeArray() w rzeczywistości wykonuje więcej kodu, ale kluczowy moment, to właśnie zwracanie tablic statycznych (3 elementowych) i umieszczanie ich wewnątrz tablicy dynamicznej.

Po prostu tablica dynamiczna ma gromadzić te trój elementowe tablice statyczne - głównie o to mi chodzi.

Przykładowo, po 5 wywolaniach funkcji giveMeArray();, tablica dynamiczna powinna wyglądać tak:

dynamicArr = [
      [ 1, 2, 3],
      [ 2, 3, 4],
      [ 34, 25, 62],
      [ 87, 54, 3],
      [99, 32, 5]
]

 

2 odpowiedzi

+2 głosów
odpowiedź 1 kwietnia 2016 przez criss Mędrzec (172,590 p.)
wybrane 1 kwietnia 2016 przez ScriptyChris
 
Najlepsza

W c++ nie da się "rozszezrać" tablic. Skorzystaj z std::vector i metody .insert ,żeby rozszerzyć go o kolejny zawartość kolejnego vectora. Z tym, że najpierw musisz return funkcji przypisać do jakiegoś tymczasowgo vectora.

#include <vector>

std::vector<int> give()
{
    std::vector<int> vec;
    vec.push_back(1);
    return vec;
}

int main() {
    std::vector<int> vec, vec2;
    vec2 = give();
    vec.insert(vec.begin(), vec2.begin(), vec2.end());
}

insert przyjmuje też wskaźniki, nie tylko iteratory, więc możesz rozszerzać ten vector o tablice, ale wtedy byś musiał w funkcji zaalokować dynamicznie tablice (żeby nie została usunięta po wykonaniu funkcji) i zwrócić wskaźnik, a po rozszerzeniu vectora usunąć ją z pamięci poza funkcją. Na pewno szybszy, ale brzydszy sposób.

#include <vector>

int* give()
{
    int* ptr = new int[3];
    ptr[0] = 1;
    ptr[1] = 2;
    ptr[2] = 3;
    return ptr;
}

int main() {
    std::vector<int> vec;
    int* p = give();
    vec.insert(vec.begin(), p, p+3);
    delete[] p;

 

komentarz 1 kwietnia 2016 przez ScriptyChris Mędrzec (190,190 p.)

Mógłbyś mi wytłumaczyć pierwszą propozycje? Dodałem komentarze dotyczące tego, czego nie rozumiem.

std::vector<int> give()   // funkcja typu "vector" ? nie przyjmuje zadnych parametrow?
{
    std::vector<int> vec;  // tworzy vector o nazwie "vec" ?
    vec.push_back(1);     // co to robi, skad ta 1 ?
    return vec;
}
 
int main() {
    std::vector<int> vec, vec2;   // tworzy vectroy  "vec" i "vec2" ?
    vec2 = give();   // umieszcza w "vec2" zwrócony vector z funkcji ?
    vec.insert(vec.begin(), vec2.begin(), vec2.end());   // tego nie rozumiem
}

 

komentarz 1 kwietnia 2016 przez criss Mędrzec (172,590 p.)
Wystarczy zajrzeć w dokumentacje std::vector i wszystko stanie się jasne.

W pierwszym komentarzu nie wiem o co ci chodzi. Tak, funkcja zwraca std::vector<int> i nie przyjmuje żadnych argumentów.

Tak, tworzy vector o nazwie vec.

.push_back() po prostu dodaje element do vectora, a vector sam dba o ewentualną alokacje potrzebnej pamięci. Ta 1 to przypadkowa cyfra z klawiatury. Dodałem do vectora 1, żeby nie był pusty (ale oczywiście to nie jest żaden wymóg).

Tak, tworzy 2 vectory o nazwach vec i vec2.

"Umieszcza". No tak. Przekopiowuje konkretnie.

.insert - zajrzyj w dokumentacje. .begin() i .end() zwracają iteratory do, odpowiednio, pierwszego elementu i elementu o 1 za ostatnim. Iteratory możesz traktować jak wskaźniki, tyle, że zamiast wskazywać na miejsce w pamięci, wskazuje na miejsce w kontenerze. Nawet jeśli teraz tego nie rozumiesz, to nie powinno ci to przeszkadzać.

.insert(vec.begin(), vec2.begin(), vec2.end()) umieszcza zawartość vec2 (ostatnie 2 argumenty to zakres elementów vec2 jakie chcemy przekazać do vec) na początku vec (pierwszy argument to pozycja gdzie mają zostać wrzucone elementy). To samo jest napisane w dokumetacji.
komentarz 1 kwietnia 2016 przez ScriptyChris Mędrzec (190,190 p.)
Ok, dzięki. Przebrnąłem przez to.
+1 głos
odpowiedź 1 kwietnia 2016 przez iwan9449 Pasjonat (20,810 p.)
Myślę, że dobrym rozwiązaniem będzie skorzystanie z kontenera jakim jest vector. Oferuje on metodę push tak samo jak w js

http://cpp0x.pl/kursy/Kurs-STL-C++/Kontener-tablicy-std-vector/119

W twoim przypadku będziesz musiał skorzystać z "vectora vectorów" :) vector<vector<int>>, na początki w pętli ładować sobie 3 liczby do vectora, a później dodać ten vector do kolejnego vectora.

Pozdrawiam!

Podobne pytania

0 głosów
2 odpowiedzi 1,489 wizyt
pytanie zadane 29 marca 2016 w C i C++ przez L33TT12 Gaduła (3,950 p.)
+1 głos
1 odpowiedź 384 wizyt
0 głosów
5 odpowiedzi 5,384 wizyt

92,760 zapytań

141,684 odpowiedzi

320,470 komentarzy

62,104 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...