Wielowymiarowe wektory

0

Witam,
ostatnio natrafiłem gdzieś w internecie na artykuł o wektorach w C++ i mówiąc szczerzę gościu tam się wypowiadający mnie przekonał.
Mam jednak kilka pytań co do tego;
-Czy to rzeczywiście tak jest z tymi wektorami, że to niby są lepsze niż tablice i zużywają mniej pamięci?
-Jak tworzy się vektory wielowymiarowe (chodzi mi tutaj o taki 4-wymiarowy)
Podrawiam.
Wesołych świąt i szczęśliwego Nowego Roku :D

1

Czy to rzeczywiście tak jest z tymi wektorami, że to niby są lepsze niż tablice i zużywają mniej pamięci?

Nie, zajmują tyle samo lub więcej miejsca. Wektor sam realokuje pamięć gdy jej potrzebuje, ale alokuje jej więcej niż potrzebujesz po to żeby przy dodawaniu elementów nie musiał realokować co chwilę. Główną zaletą jest to, że nie musisz się w to ręcznie bawić, a działa on praktycznie tak samo jak ręcznie alokowana tablica. Osobiście używaj vectorów, list, map, ... gdzie się tylko da, ale używaj tylko tej struktury której rzeczywiście potrzebujesz.

Jak tworzy się vektory wielowymiarowe (chodzi mi tutaj o taki 4-wymiarowy)

vector< vector<typ> vector_dwuwymiarowy;
vector< vector< vector<typ> > > vector_trojwymiarowy; (zwroc uwage na spacje miedzy > >, nie wolno jej pominąć)

0

Nie mam teraz przy sobie kompilatora jednak spytam dla pewności:
Wektor cztero(czwór?)wymiarowy robi się tak:
vector< vector< vector< vector<typ> > > > nazwa_vectora;
?
No i jak przypisać wartości do tego np. czwartego wymiaru?
nazwa_vectora[0][0][0][4] = liczba?

0

Jesli nie nadasz mu wczesniej wielkosci to wtedy musisz np. do tego ostatniego wymiaru wrzucic caly vector push.backiem tab[0][0][0].push_back(tab2) gdzie tab 2 bedzie vectorem 1 wymiarowym. Dokladnie skladni teraz nie pamietam, bo z pamieci, ale jakos tak to wygladalo.

0
Krycho napisał(a)

Jesli nie nadasz mu wczesniej wielkosci to wtedy musisz np. do tego ostatniego wymiaru wrzucic caly vector push.backiem tab[0][0][0].push_back(tab2) gdzie tab 2 bedzie vectorem 1 wymiarowym. Dokladnie skladni teraz nie pamietam, bo z pamieci, ale jakos tak to wygladalo.

Nie do końca rozumiem.
Chcę dodać po prostu w odpowiednie miejsce liczbę (int) i zastanawiam się czy taki sposób jest poprawny:

vector< vector< vector< vector<int> > >  > nazwa_vectora;
nazwa_vectora[0][0][0][4] = 1;

EDIT:
No i rozumiem że vektory nie będą powiększać się automatycznie jeśli będę chciał dodać dane poza zakresem. Co wtedy zrobić?

0

Jest tak ze jesli tworzysz

vector <int> nazwa

to wtedy taki vector jakby nie ma wielkosci i kazdy element trzeba mu dodawac poprzez nazwa.push_back(int). Natomiast jesli stworzysz vector <int> nazwa(5)

 to masz 5 elementowy vector i mozesz normlanie mu przypisac nazwa[0]=1
Przy wiekszych vectorach jest to samo. Tylko w nawiasie wielkosc sie podawalo jakos(przy 2 wymiarach) 
```cpp
vector< vector<int> >nazwa(4, vector <int>(4))

i masz vector 4 na 4 gdzie mozesz sie odwolywac poprzesz nazwa[0][0]. Dalej analogicznie.

0
Krycho napisał(a)

Jest tak ze jesli tworzysz

vector <int> nazwa

to wtedy taki vector jakby nie ma wielkosci i kazdy element trzeba mu dodawac poprzez nazwa.push_back(int). Natomiast jesli stworzysz vector <int> nazwa(5)

to masz 5 elementowy vector i mozesz normlanie mu przypisac nazwa[0]=1
Przy wiekszych vectorach jest to samo. Tylko w nawiasie wielkosc sie podawalo jakos(przy 2 wymiarach) 
```cpp
vector< vector<int> >nazwa(4, vector <int>(4))

i masz vector 4 na 4 gdzie mozesz sie odwolywac poprzesz nazwa[0][0]. Dalej analogicznie.

Nadal nie kumam wszystkiego:

kazdy element trzeba mu dodawac poprzez nazwa.push_back(int).

Rozumiem że "int" to jakaś liczba i nie podaję tutaj typu zmiennej.
A jeśli chciałbym dodać element z drugiego wymiaru? Czy jak to działa?
No bo teraz opisałeś chyba jak to się robi przy wektorach jednowymiarowych. Ja natomiast chcę używać 4-wymiarowych. Jak więc mam dodawać elementy do takiego wektora?

1
#include <iostream>
#include <vector>

using namespace std;
int main()
{
    vector< vector< vector< vector<int> > > > tab;
    vector< vector< vector<int> > >tab4;
    vector< vector<int> >tab2;
    vector<int> tab3;
    tab3.push_back(5);
    tab3.push_back(2);
    tab2.push_back(tab3);
    tab4.push_back(tab2);
    tab.push_back(tab4);
    cout << tab[0][0][0][0]; //5
    cout << tab[0][0][0][1]; //2
    return 0;
}

Masz wektor 4 wymiarowy. Jesli nie masz sprecyzowanej wielkosci musisz mu robic cos takiego. Najpierw najbardziej podstawowy wektor 1 wymiarowy. Dodajesz elementy i wrzucasz do 2 wymiarowego caly wektor. Potem do 3 i na koncu do 4. To jest tak jakby kazdy element tego 4 wymiarowego wektora byl wektorem 3 wymiarowym. Nie potrafie tego dobrze wyjasnic po prostu tak jest ;).

2
 vector< vector<int> >      JestemWektorem(4, vector<int>(4)); 

Dwuwymiarowy wektor 4x4
Analogicznie robi się czterowymiarowy:


//vector< int > //1D
//vector< vector< int > >  //2D  
//vector< vector< vector< int > > >  //3D
//vector< vector< vector< vector< int > > > > //4D

vector< vector< vector< vector< int > > > >  JestemWektorem(4, vector< vector< vector <int> > >(4,  vector< vector<  int > >(4, vector< int >(4, -1) ) ) );
//Czterowymiarowy wektor intów, o startowym rozmiarze 4x4x4x4, wypełniony domyślnie w całości wartością -1;

JestemWektorem[0][0][0][2]=5;
JestemWektorem[3][3][3][3]=-2;
JestemWektorem[0][1][2][3]=0;

cout << JestemWektorem[0][0][0][2] << endl << JestemWektorem[3][3][3][3] << endl << JestemWektorem[0][1][2][3] << endl << JestemWektorem[3][2][1][0];
//Wypisujemy co wpisaliśmy i jedno inne, żeby zobaczyć, że się dobrze wypełniło na starcie.

Potem możesz go sobie poszerzać za pomocą resize() albo dodawać elementy na wierzch przez push_back().
Oczywiście3 wygodniej byłoby sobie zrobić jakieś typedefy do tego, na przykład tak jak tutaj - http://www.daniweb.com/software-development/cpp/threads/137814


typedef  vector<int>       vector1D;
typedef  vector<vector1D>  vector2D;
typedef  vector<vector2D>  vector3D;
typedef  vector<vector3D>  vector4D;

vector4D JestemWektorem(4, vector3D(4, vector2D(4, vector1D(4,-1) )  ) );

JestemWektorem[0][0][0][2]=5;
JestemWektorem[3][3][3][3]=-2;
JestemWektorem[0][1][2][3]=0;

cout << JestemWektorem[0][0][0][2] << endl << JestemWektorem[3][3][3][3] << endl << JestemWektorem[0][1][2][3] << endl << JestemWektorem[3][2][1][0];

Na przykład tak.

1

dodam jeszcze, że w C++11 nie trzeba kombinować z osobnym wypełnianiem push_backami podwektorów i podwektorów tych podwektorów, tylko można zapodać takiego kombosa:

  vector<vector<vector<vector<int>>>> tab = 
  {{{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}}},
   {{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}}},
   {{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}}},
   {{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}},{{1,2,3},{1,2,3}}}};

  cout << tab[1][1][1][1] << endl;

a nawet

const vector<vector<vector<vector<int>>>> tab = // itd.

— spróbujcie to zrobić z constem w poprzednim standardzie…

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0