Wielowymiarowe wektory

Odpowiedz Nowy wątek
2011-12-27 16:26
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

Pozostało 580 znaków

2011-12-27 16:31
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ąć)


░█░█░█░█░█░█░█░█░█░█░█░
Btw, spacja jest niepotrzebna w C++11. - Endrju 2011-12-27 16:38
dopóki większość używa starszej wersji lepiej o niej wspomnieć :) ale przyznam, że nie wiedziałem o niej mimo że mam najnowszą wersje :P - krwq 2011-12-27 16:49

Pozostało 580 znaków

2011-12-28 11:13
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?

Pozostało 580 znaków

2011-12-28 11:22
Krycho
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.

Pozostało 580 znaków

2011-12-28 11:26
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ć?

edytowany 1x, ostatnio: Losiu22, 2011-12-28 11:27

Pozostało 580 znaków

2011-12-28 11:42
Krycho
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.

Pozostało 580 znaków

2011-12-28 12:31
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?

edytowany 1x, ostatnio: Losiu22, 2011-12-28 12:31

Pozostało 580 znaków

2011-12-28 14:54
Krycho
#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 ;).

Pozostało 580 znaków

2011-12-28 15:13
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.

edytowany 2x, ostatnio: Jadeszek, 2011-12-28 15:19

Pozostało 580 znaków

2011-12-28 17:49
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…

edytowany 2x, ostatnio: Azarien, 2011-12-28 17:52
a jest jakiś powód, żeby do takiej tablicy używać const vectora zamiast const tablicy? - 0x200x20 2011-12-28 18:14
Oczywiście. Funkcja xyz może wymagać podania jej czterowymiarowego vectora. Jeżeli użyjesz go tylko raz miło jest zadeklarować go const. - Endrju 2011-12-28 18:35

Pozostało 580 znaków

2011-12-28 18:46
0
Azarien napisał(a)

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
> 
```cpp
const vector<vector<vector<vector<int>>>> tab = // itd.

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

OK. Wszystko jasne :D
Tak z ciekawości spytam: jak sprawdzić jakie mam C++?
Mówiąc szczerze nigdy nie wiedzialem że istnieją rózne wersje tego języka.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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