PDA

Tam Sürümünü Görmek İçin : vector<vector<x>*>


ceeyt
02/05/2004, 02:43
ic ice vektorler yerlestirmek(bu ic ice yerlestirme olayina taktim heralde :tamams: ) icin asagıdaki gibi biseyler yazdim.



class y{
public:
y(const int &n1,const int &n2):n_1(n1),n_2(n2){}
int n_1;
int n_2;
};

int main(int argc, char* argv[])
{


int n1,n2;

vector<y> y_vec;

vector<y> *p =new vector<y>();

vector<vector<y>*> vec_vec;

n1=1;
n2=2;

p->push_back(y(n1,n2));

vec_vec.push_back(p);



cout << (*vec_vec.begin())->begin()->n_1
<<" - ";
cout << (*vec_vec.begin())->begin()->n_2;


vector<y>::iterator y_itr;
vector<vector<y>*>::iterator vecvec_itr;

y_itr=vecvec.begin();
vecvec_itr=vec_vec.begin();


return 0;
}


x-y dorularina paralel yerlestirilmis iki vektor gibi.ana vektorun elemanlari baska vektorler.Ana vektorun ilk elemani olan vektorun ilk elemanina ki bu da iki int tutan bir class erismek icin
*(vec_vec.begin)->begin()->n_1 ise yariyor.

buraya kadar guzelde diger elemanlar icin durum biraz karisiyor.Her elemana erismek icin biri ana vektorde biri alt vektorlerde hareket eden iki vektor dusunursek;

*(vec_vec.begin())->begin()->n_1 isini yapan ,ana vektorun ilk elemani olan vektorun ilk elamanina erisecek her iki iteratorunde adresleri ana vektorun baslangic adresi ( vecvec.begin() ) mi olacak?Bu durumda *vecvec_itr-> dedigimde eleman vektorunun tuttugu sınıf icindeki degiskenlere ulasabiliyor olmam gerekmez mi?
cout <<*vecvec_itr->n_1; gibi.Ama olmuyor...
Ayrica ana vektorun ikinci elemani olan vektorun diyelim ki 4. elemanina erismek istiyoruzBu durumda

y_itr=vec_vec.begin()+1;

*(y_itr+3)->n_1; *(y_it+3)->n_2; olmali diye dusunuyorum ama olmuyor dmek ki yanlis....


Dusunelim ki ana vektorun ilk elemani olan vektore bir seyler ekledik.Sonra ana vektorun ikinci elamanina bir seyler ekledik.Bu durumda ana vektorun ikinci elemani olan vektorun baslangic adresini ana vektorun baslangic adresi+1 dediysek.(vec_vec.begin()+1)

burada ana vektorun ikinci elemani icin iteratorunun degeri ilk elemanda tutulan bilginin buyuklugune bagli olarak mi artar?Yani

(vec_vec.begin()+1) - vec_vec.begin() = ilk eleman olan vektordeki bilgiye bagli bellek araligi.

Boyleyse herhangi bir elemana erismeden once mutlaka her seferinde eleman olan vektorlerin ana vektorun balangic adresine gore degismis adreslerine ihtiyacimiz olacak.

derdime deva olsun diye asagidaki gibi bir sey kullanmak istedim ayni sorunlar burda da var.



class y {
public:
int n_1;
int n_2;
};

class yy {
public:
vector<y> y_vec;
vector<y>::iterator yvec_itr;
};

class yyy {
public:
vector<yy> vec_vec;
vector<yy>::iterator vecvec_itr;
};


int main(int argc, char* argv[])
{
y Y;
yy YY;
yyy YYY;

Y.n_1=1;
Y.n_2=2;

YY.y_vec.push_back(Y);
YYY.vec_vec.push_back(YY);

Y.n_1=3;
Y.n_2=4;

cout << YYY.vec_vec.begin()->y_vec.begin()->n_1
<< " - ";
cout << YYY.vec_vec.begin()->y_vec.begin()->n_2;


return 0;
}


ana vektorun ilk elemani olan vektorun ilk elemani icin her sey guzel de iteratorlerle yapamaya kalkinca....

anlatmak istediklerimi buyuk ihtimalle anlatamadim,ama olsun.

sabir gosterip buraya kadar okuduysaniz tesekkur ederim...


Arkantos
02/05/2004, 04:31
Sadece birinci kodu okuyabildim.
Bende şu satır çalışmadı :
y_itr=vecvec.begin();
Bence şu satırlar yerine:
int n1,n2;
n1=1;
n2=2;

direkt şu şekilde kullanılabilirmiş:
p->push_back(y(1,2));
Ayrıca bir sınıfın veri üyelerini genel erişime açmak pek iyi bir fikir değil. (Sarma gereği) n_1 ve n_2'yi de private olarak tanımladığımızda şu satırlar da geçersiz hale geliyor.Bunun yerine DegerOgren() gibi üye işlevler yazabiliriz:

cout << (*vec_vec.begin())->begin()->n_1 <<" - ";
cout << (*vec_vec.begin())->begin()->n_2;

Bir de genel olarak bu kodla ne yapılmak istendiğini ve neden sınıfları kullandığımızı anlamadım :confused:

ceeyt
02/05/2004, 19:58
bende calısmadı dediğin yerde vec_vec.begin() olacak alt cizgi eksik olmus.

Class üyelerini public yapmak iyi bir fikir degilde simdilik ana problemleri halletmek istiyorum,erisim problemleri tamamen bittikten sonra private: olacaklar zaten.

Bu bana sunun icin gerekli:
Bir sistemden bana farklı isimler altinda hata mesaji dosyalari gelecek.kac farklı hata mesaji dosyasi gelecegi belli degil,ayrica her hata sosyasi altinda kac tane hata olacagi da belli degil.Ayrica bir dosya altindaki her mesaj hatanin isminden ve kisa tanmindan olusacak yani aslinda ilk class icindeki degerler

int n_1,n_2 degilde
string s_1,s_2 olacak gibi dusunebiliriz.

ilk once dosyayi aliyorum,bu dosyada hangi hatalarin geldigine bakip ana vektorde ilgili elemana gidiyorum(bu elemanda aslinda bir vektor),
sonra dosya icindeki degerleri tek tek ilgili vektore yerlestiriyorum.

sınıfları ilk yazdigimdaki erisim problemlerini ortadan kaldirabilir miyim diye benzer bir sey yazmak icin kullandim.Aslinda mantigi benzer zaten benzer sorunlar cikti.

acehreli
03/05/2004, 19:50
ceeyt, sablonlar kullanirken isleri kolaylastirmak icin bol
bol typedef'ler kullanmani oneririm. Aslinda sen de y, yy ve
yyy siniflarini ayni amacla kullanmak istemissin galiba.

Ayrica, kullandigin toplulugun vector veya deque olacagindan
eminsen, okumayi kolaylastirmak icin operator[] islecinden
de yararlanabilirsin.

Ozellikle begin()->begin() gibi zincirlenmis kullanimlar
benim icin cok karmasik olur.

Ben kendi kodlarimda soyle kolayliklar kullaniyorum. (Bu
yaziyi kullandigim bilgisayarda derleyici olmadigi icin
hatalar olabilir. Ozur...)

Cogu zaman gostergelere de bulasmak zorunda kalmayiz...


struct HataMesaji
{
/* sakladigim bilgi her ne ise... */
};

typedef vector<HataMesaji> HataDosyasi;
typedef vector<HataDosyasi> HataDosyalari;

HataMesaji mesajOku(istream & giris)
{
/* Hata mesajini olusturan oge tanimlari
(int, string, vs.)

int sayi;
string mesaj;
vs...
*/
giris >> sayi >> mesaj >> /* vs. */;

return HataMesaji(sayi, string, /*vs.*/);
}

HataDosyasi dosyaOku(string const & dosyaAdi)
{
ifstream kutuk(dosyaAdi.c_str());

HataDosyasi dosya;
HataMesaji hata;

while (/* hata mesaji oldugu surece */)
{
dosya.push_back(mesajOku(kutuk));
}

return dosya;
}

void foo()
{
HataDosyalari dosyalar;

while (/* dosya oldugu surece */
{
string dosyaAdi = /* ... */
dosyalar.push_back(dosyaOku(dosyaAdi));
}

/* Sira kullanmaya geldiginde ise, gereksiz
kopyalamalari onlemek icin saklanan bilgiye
referanslar kullanarak erisebiliriz:
*/
HataDosyasi const & dosya = dosyalar[0];
hataMesaji const & mesaj = dosya[0];

cout << mesaj << '\n';
}


Umarim bu tarz kullanimin isleri kolaylastirdigina
gosterebilmisimdir... :)

Ali

ceeyt
04/05/2004, 00:38
tavasiyelerinize uyarak tekrar denerim,tesekkur ederim...

ama becerebilecek miyim emin degilim :)

acehreli
04/05/2004, 02:10
Yukaridaki "derlenmemis" kod orneginde gordugum bir hatayi

dosya.push_back(hataOku(dosya));

satirini

dosya.push_back(haaOku(kutuk));

seklinde degistirerek giderdim. (Umarim :) )

Haklisin ceeyt, kodda yanitlanmasi gereken noktalar
var. Ornegin bir dosyanin sonuna gelindigini anlamak...

Onemli olan, kodu birbirinden bagimsiz parcalara ayirarak
yazabilmek. Ornegin dosya okumak icin kullanilan dosyaOku
islevi, ust duzey dosya okuma isini ustlenmis; tek bir
hatanin dosyadan nasil okundugunu mesajOku diye ayri bir
islev biliyor.

(Bu arada baska bir hatami daha gordum ve duzelttim:

dosya.push_back(hataOku(kutuk));

yerine

dosya.push_back(mesajOku(kutuk));

olacakmis. :) )

Ali