PDA

Tam Sürümünü Görmek İçin : push_back() ile ..


PUNK
09/07/2005, 22:23
using namespace std;
vector<double>izgx(1);
vector<double>izgy(1);
....
.....

for(i=1;i<x_izg_say;i++){izgx.push_back(izgx[i-1]+xac);}

[C++ Warning] Unit4.cpp(64): W8012 Comparing signed and unsigned values

borland c++Builder bu kodu derliyor istediklermi yapıyor ama Bu satır için bu uyarıyı veriyor ne demek istiyor acaba


PUNK
09/07/2005, 22:26
vektörle ilgisi yokmuş halllettim :)

acehreli
09/07/2005, 22:29
push_back ile bir ilgisi oldugunu sanmiyorum. i ve x_izg_say ayni turden degiller; birisi isaretli, digeri isaretsiz bir tur.

Oyle oldugu zaman, i<x_izg_say gibi bir karsilastirma dogru calismayabilir. Derleyici seni bu konuda uyariyor. i ve x_izg_say'in ayni turlerde olmasini sagla.

Ali

PUNK
11/07/2005, 01:05
public:

vector<double> a(10);//

bu satır için ) excepted :) diyo Borland c++

vector<double>a[10]; şeklinde tanımlamak ne anlama geliyor bunu kabul ediyor

:)

sckz
11/07/2005, 01:55
10 tane vector<double> sınıfına ait nesne oluşturursun... yani vector<double> ın dizisi.. tek bir vektör değil.. vektörlerin dizisi ni oluşturuyorsun...

bu arada msvc 7 vector<double> a(10); satırını sorunsuz derliyor..

acehreli
11/07/2005, 05:33
Oradaki 'public'ten anladigim kadariyla, PUNK o satiri sinif tanimi icinde yazmis; onun icin derlenmiyor.

PUNK, nesneyi sinif tanimi icinde "bildir" ve kurucuda "kur":


#include <vector>
#include <iostream>

class Sinif
{
// Bildirim:
std::vector<double> sayilar_;

public:

Sinif()
:
sayilar_(10) // <-- kurulum
{}

void soyle() const
{
std::cout << "Toplam " << sayilar_.size()
<< " sayi var.\n";
}
};

int main()
{
Sinif nesne;
nesne.soyle();
}


Bu arada, son zamanlarda buyuklugu bastan belirlenen cok vector gormeye basladim. Buna gerek olmadigini herkes biliyor degil mi? vector'u bos olarak olusturup tamamen push_back'lerle doldurabiliriz.

Ali

sckz
11/07/2005, 05:36
Oradaki 'public'ten anladigim kadariyla, PUNK o satiri sinif tanimi icinde yazmis; onun icin derlenmiyor.
aman allahım.. ya nasıl gözden kaçırdım..

mr1yh1
11/07/2005, 13:09
@punk
warning lere fazlaca takılma , çoğunlukla uyarının neden kaynaklandığını bilmen yeterli..
mesela yukarıdaki uyarı yüzünden, değişkenlerin türlerini düzeltmen gerekmiyor..

acehreli nin dediği gibi :
vector<double> a(10) ; bunu hiç kullanma daha iyi..
doğrudan vector<double> a yazabilirsin.
buradaki a adında bir vector ( bir tür dizi ) tanımladın...
a[0] , a[1] ... vectorün elemanları...


vector<double> a[10] ; ise çok farklı,
burada 10 tane vector (dizi) tanımladın.. ( sckz nin söylediği vector dizisi )
a[0][1] , ilk vektörün , ikinci elemanı...
a[0][2] , ilk vektörün üçüncü elemanı...
yani bir başka şekliyle:
vector<double> a0;
vector<double> a1;
...
vector<double> a9;
tanımlamış gibi oldun...

acehreli
11/07/2005, 18:57
mr1yh1, derleyici uyarilarina takilmadigi zaman cok onemli bir sorun ortaya cikiyor ama: Proje buyudukce uyarilarin sayisi o kadar artiyor ki, artik onlara hic bakilmamaya baslaniyor.

Gercekten ise yarayan uyarilar da arada gozden kaciyorlar tabii ki. Bu durumda en mantikli sey, hic uyari olmadan derlemeyi hedeflemektir. Hatta en iyisi, benim ozel programlarimda ve daha onceden calistigim bazi yerlerde yapildigi gibi, tek bir uyariyi bile hata olarak degerlendirip daha ileriye gitmemektir.

gcc'nin -Werror secenegi uyarilara hata gozuyle bakilmasini saglar.

Ali

mr1yh1
11/07/2005, 20:54
haklısın , bununla daha önce karşılamıştım, ciddi sorun yaratıyor, yüzlerce gereksiz mesaj doluyor ekran..
en baştan sıfır hatayı hedeflemek en sağlamı.. :)

PUNK
11/07/2005, 23:50
bişey soracam push_back fonsiyonu c deki realloc gibimi çalışıyor örneğin vektor buyuduk ce arka arkaya boş bellek bulamayınca vektoru alıp o boşluğu bulduğu biyeremi taşıyor yada nasıl yapıyor :)

sckz
11/07/2005, 23:53
evet öyle yapıyor..
böyle bir durumda nesneler büyükse programına yük biniyor.. Bu durumda yapman gerekenler ya başka bir container arayışına gitmek (ör: list gibi bir container kullanmak) ya da nesnelerin kendini tutmak yerine onlara işaret eden nesneleri tutmak..

acehreli
12/07/2005, 00:13
Programa binen yuk yok denecek kadar azdir: her bir nesnenin eklenmesi sabit zamanda olusur (amortized constant time). Yeni ayrilan bellek bir oncekinin belirli bir kati oldugu icin, nesne basina dusen bellek ayirma zamani gittikce kuculur ve kalabalik topluluklarda sifir olarak kabul edilir.

Uygulamadan anlasildigina gore, vector::reserve oge islevinin kullanimi bile gereksiz kabul edilir. Gonul rahatligiyla push_back! :)

Ali

sckz
12/07/2005, 00:49
Yeni ayrilan bellek bir oncekinin belirli bir kati oldugu icin, nesne basina dusen bellek ayirma zamani gittikce kuculur ve kalabalik topluluklarda sifir olarak kabul edilir.bu cümlenizi tam anlamadım aslında..

benim düşüncem : eğer vektör dolmuş ise ve bu vektöre yeni bir nesne eklersek, vektör içinde barındırdığı nesneleri taşıyacaktır.. Buraya kadar sorun yok.. peki ama eğer nesnelerimiz büyükse bu işlem yavaş gerçekleşmez mi?

acehreli
12/07/2005, 01:04
Oncelikle, soyledigine karsi cikmadigimi belirtmek isterim. Soylemek istedigim, vector'un push_back nedeniyle yavas kabul edilmemesi gerektigidir.

Evet yavas gerceklesir ama yavaslik goz ardi edilecek kadar kucuktur. Cunku yeniden bellek ayirma ve nesneleri kopyalama islemi nesne sayisi arttikca nesne sayisi yaninda kucuk kalir. Uygulamada cogunlukla farketmez. Farkettigi durumlarda da, tanim geregi "gerektigi icin" 'reserve' kullanabiliriz.

Bjarne Stroustrup da bir mesajinda "siradan kod icinde reserve kullanmayi biraktigini" soyluyor:

http://groups-beta.google.com/group/comp.lang.c++.moderated/browse_thread/thread/b3d9815f5b792f5d/5967e6b5952f1234?q=vector++(reserve)+author:Bjarne +author:Stroustrup&rnum=1&hl=en#5967e6b5952f1234

Ali

Volkan Uzun
12/07/2005, 01:13
bence en guzeli, sckz googleda amortized constant time arat.

sckz
12/07/2005, 17:02
walla arattım.. şöle bişi buldum : http://www.cppreference.com/complexity.html
bu constant time olayı nı hala anlamış değilim aslında.. birçok sitede şöyle bişi gördüm "push_back() runs in constant time."

birde yine aynı site da : // create a vector of random integers
cout << "original vector: ";
vector<int> v;
for( int i = 0; i < 10; i++ ) {
int num = (int) rand() % 10;
cout << num << " ";
v.push_back( num );
}
cout << endl;
// find the first element of v that is even
vector<int>::iterator iter1 = v.begin();
while( iter1 != v.end() && *iter1 % 2 != 0 ) {
iter1++;
}
// find the last element of v that is even
vector<int>::iterator iter2 = v.end();
do {
iter2--;
} while( iter2 != v.begin() && *iter2 % 2 != 0 );
cout << "first even number: " << *iter1 << ", last even number: " << *iter2 << endl;
cout << "new vector: ";
vector<int> v2( iter1, iter2 );
for( int i = 0; i < v2.size(); i++ ) {
cout << v2[i] << " ";
}
cout << endl;
All of these constructors run in linear time except the first, which runs in constant time.

demişler.. push_back taki constant time, her eklenen eleman için geçen süre nin aynı olduğu herhalde.. çünkü elemanı sona ekliyoruz.. ve ekleme hızı, eleman sayısına ya da başka birşeye bağlı değil..

saçmalıyor muyum?...

Pliz help mi..

acehreli
12/07/2005, 23:59
Evet, "constant time" bu baglamda topluluk buyuklugunden bagimsiz demektir.

Ornegin vector ne kadar buyuk olursa olsun, operator[] isleci ile nesnelere erismek sabit zaman alir; vector'un buyuklugunden bagimsizdir.

push_back ise "amortized constant time"dir. Bu da, senin de gozlemledigin gibi ekleme isleminin bazen uzun zaman alacagi, ama bu masrafin vector'deki eleman sayisi arttiginda sifira gidecegi anlamina gelir.

Bunu denemek aslinda cok kolaydir: bir dongu icinde push_back kullanarak uzunluklari 1'den baslayarak artan vector'ler olustur. Butun vector'u olusturmak icin gecen zamani olc; her bir nesne icin gecen zamani bulmak icin vector'un uzunluguna bol. Bakalim vector'leri oge eklemek icin gecen zaman vector'lerin sonuc uzunluklariyla nasil degisiyor...

Not: Bu arastirmayi yapacagin icin tesekkur, ve sonuclari baska bir konuya yazmani rica ederiz. :)

"linear time" ise islemin topluluk buyuklugu ile dogru orantili oldugunu soyler. Yukaridaki son iki dongude nesnelere bastan sona dogru teker teker bakildigi icin, o islemler "linear time"dirlar. 100 nesne icin ortalama 50 kere, 1000 nesne icin ortalama 500 kere bakilir.

Dur bir dakika yahu! :) Aslinda cift degerli ilk nesneyi aradigimiza gore, ve rastgele yerlestirildiklerine gore, bence ilk cifti bulmak da sabit zamanda olur. Cunku %50 olasilikla cift olduguna gore, ilerledikce cift bulamama sansi buyuk olcude duser.

Cift aramak yerine, hepsi degisik degerli nesneler icinden belirli bir degeri arasalar o zaman "linear time" olurmus.

Ali

Volkan Uzun
13/07/2005, 00:56
@acehreli :) , worst hesabi yaaprsak tam lineardir, n uzunlukta bir vectorde n kere bakarsin dim ? yani sanirim bu konularda ortalama degilde worst case konusuyoruz ? gerci ortalamada (worst+best )/2 ve 1/2 sabit oldugundan aslinda worst case cok saglikli ve anlamasi daha kolay sanirim

Euclides
13/07/2005, 04:00
Programa binen yuk yok denecek kadar azdir: her bir nesnenin eklenmesi sabit zamanda olusur (amortized constant time). Yeni ayrilan bellek bir oncekinin belirli bir kati oldugu icin, nesne basina dusen bellek ayirma zamani gittikce kuculur ve kalabalik topluluklarda sifir olarak kabul edilir.

Uygulamadan anlasildigina gore, vector::reserve oge islevinin kullanimi bile gereksiz kabul edilir. Gonul rahatligiyla push_back! :)

Ali

Ali'ciğim biliyorsun benim c++ zayıf... anlamadığım bir nokta var acaba biraz daha açman mümkün mü ?

Eğer bunlar vector değilde doulbe/single linked list olsaydı sana tamamen katılacaktım. Fakat belirbir eklemeden sonra vector genişlemek isteyecek ve realloc'a bezner bir işlem yapacaktır. Bunu düşünmemin nedeni belirli bir eklemeden sonra vector'un 1. elemanının adresinin değişmesi. Yani bazı *sihirli* neseler vector'un uzunluğuna göre çok yavaş eklenir diyemezmiyiz ? Yoksa vector'ler linked list mi ?

ceeyt
13/07/2005, 05:50
Su ana kadar okuduklarimi yanlis anlamissam duzeltin lutfen.

std::vector ile baslangicta bir reserve islevi kullansak da kullanmasak da, sanirim std::vector un tampon buyutme stratejisinden dolayi nesne sayisi cok arttiginda
(bir push_back icin gecen sure/ ayrilmis bellek miktari ) otomatikman sifira yaklasiyor.

Yani biz 1000. push_back'i yaparken belki savurgan bir derleyici sonraki 100 eleman icin tamponu buyutmus olabilir ve ilk elemanin adresi degisipte genelden uzun suren bir push_back olusmussa bile sonraki yaklasi (100 * 2) push_back icin ilk elemanin adres degistirmesi soz konusu olmuyor. Boylece genelden uzun suren push_back islemi de (bellek ayirma suresi / ayrilmis bellek) olarak kuculmeye devam ediyor.

Tabii burda
Yani bazı *sihirli* neseler vector'un uzunluğuna göre çok yavaş eklenir diyemezmiyiz ? nin cevabini merak ediyorum.

Sonuc olarak eger konuyla ilgili bir sorun hissediyorsak bu push_back ile ilgili degil std::vector secimimizle ilgili diyebilir miyiz?

Volkan Uzun
13/07/2005, 08:14
vector sanirim her yeni realloc isleminde geometrik olarak artarak yer ayiriyor
ornek ilk boyut 1 ise, ilk reserve 2, sonra 2 dolunca 4, 4 dolunca 8
bununda limitini alirsaniz aslinda teorik olarak bir sure sonra yer ayirma islemi yapmayacaktir ( genelde algoritmalarda bu tip n ler cok buyuk varsayilir ) .

acehreli
13/07/2005, 09:52
sanal_programci'nin dedigi gibi...

Aslinda bir vector gerceklemesinde push_back'in N'ye bagliliga bakmak konuya ayrica isik tutacak. Onu da sckz'den bekliyoruz :)

Euclides, standart topluluk islemlerinin karmasikliklari standart tarafindan belirlenmistir. Standart vector'un push_back'inin "amortized constant time" oldugunu da soyler. Buna bir de nesne erisiminin sabit zamanda (O(1)) olmasi geregi eklenince vector'un aslinda bir dizi olarak gerceklendigini dusunebiliriz.

Aslinda vector ayni sartlari saglayacak sekilde deque gibi kopuk dizi parcalarindan da olusturulabilir; cunku deque de ayni karmasiklik sartlarini saglar. Hicbir gerceklemenin boyle yapmadigi anlasildiktan sonra, standart vector'un aslinda bir dizi olarak gerceklenmesi gerektigini sart kosmustur.

Yani vector'un butun nesneleri art arda bir dizi gibi oturmak zorundadirlar. Boylece vector, ilk nesnesinin adresi alinarak bir C dizisi gibi kullanilabilir:


void dizi_alan_bir_islev(int * sayilar, size_t adet);

vector<int> sayilar;
/* sayilar'i doldurmus olalim */

// Ilk nesnenin adresini ve nesne adedidi gonderebiliriz:
dizi_alan_bir_islev(&sayilar[0], sayilar.size());


Boylece C arayuzlerinde de vector kullanabiliriz.

Ali

PUNK
16/07/2005, 06:08
uğraştığım bir program içerisnde yoğun matris işlemleri yapılan bir kısım var problemin buyukluğune göre buradaki işlem süresi 5 dk falan olabiliyor bazen bu işlemler yapılırken ben hiç biişey yapamıyorum programın dier fonksiyonlarını kullanamıyorum yani işlem bitinceye kadar mudahele edemiyorum program, bu matris işlemlerini yaparken ben programın başka bir kısımnı kullanablirmiyim boyle bi olanağım varmı :D

Volkan Uzun
16/07/2005, 07:17
var, eger islem yapan kismini thread yaparsan bu mumkun

mr1yh1
16/07/2005, 14:49
uğraştığım bir program içerisnde yoğun matris işlemleri yapılan bir kısım var problemin buyukluğune göre buradaki işlem süresi 5 dk falan olabiliyor ...

...
garanti kod ile ilgili bir durum..
-fonksiyonlara nesnelerin kendilerini değil , referans ya da işaretçi gönder..
add(Matris A, Matris B) yerine add(Matris &A, Matris &B) gibi..

-sin, cos vs.. değerlerini dizilerde tut, fonsiyon olarak çağırma.. sinus[30]=0.5 gibi..

-işlemlerin sayısını azaltabilirsin.. eğer söylediklerin grafiklerle ilgili ise scenegraph ile ilgili biraz araştır..

PUNK
16/07/2005, 17:41
mr1yh1 bu zamanı kısaltmanın bi yolu yok galiba belki sen kodlasan biraz daha kısalır ama yinede uzun olur :D kodla ne ilgisi olsunki 1000*1000 iki matrisi carpmak carpımın tarnspozunu almak ..vs bunun gibi ard arda işlemler var sin[30]=0.5 diyosun ama bana sin30.002154 da lazım oluyor :s008:

mr1yh1
17/07/2005, 03:09
1000x1000 lik matrisleri ne amaçla kullanıyorsun ? :confused:

PUNK
17/07/2005, 03:15
inşaat muh öğrencisiyim yapı analizi yapan bişey yazmaya calışıyorum 20 katlı normal bir binanın analizi için bahsettiğim matrisler çok daha fazla buyuklukte olabiliyor grafikle pek ilgisi yok yani. Dediğin gibi yaptım fonsiyonlara sadece işaretçilerini yolladım :D