Jump to page: 1 2
Thread overview
Dizilerle ilgili bir soru
Nov 14, 2017
cos00kun
Nov 14, 2017
erdem
Nov 14, 2017
cos00kun
Nov 14, 2017
cos00kun
Nov 15, 2017
cos00kun
Nov 17, 2017
cos00kun
Nov 17, 2017
cos00kun
November 14, 2017

şöyle bir kodumuz var;

1 import std.stdio;
2 import std.algorithm;
3 void main(string[] argv)
4 {
5	int[5] dizibes=[8,2,0,7,5];
6	int[5] dizialti=[9,3,6,1,4];
7	int[] dizitoplam=dizibes~dizialti;
8	writeln("ikisini topladım ve sıraladım.....",sort(dizitoplam));
9	writeln("5.elemanı çıkarttım ve yazdırdım..",dizitoplam.remove(5));
10   writeln("Tekrar yazdırdım..................",dizitoplam);
11   readln();
12 }

ve çıkan sonuç;

ikisini topladım ve sıraladım.....[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5.elemanı çıkarttım ve yazdırdım..[0, 1, 2, 3, 4, 6, 7, 8, 9]
Tekrar yazdırdım..................[0, 1, 2, 3, 4, 6, 7, 8, 9, 9]

şimdi burada programın 9 ve 10 satırındaki kodun aynı sonucunu bekliyordum açıkçası neden böyle bir sonuç verdiğini anlayamadım.. belki C++ alışkınlığından belki bir başka sebepten bilemiyorum ancak normalde "dizitoplam.remove(5)" i yazdırdığımızda zaten "dizitoplam" ı yazdırmış olmuyormuyuzki ikinci "dizitoplam" da farklı bir netice çıksın ??

konuyla ilgili Ali beyin kitapta yazdığı gibi removenin dizi boyutunu değiştirmediğini saedece aradan çekip kaydırdığını anlayabilsem bile benim esas merak ettiğim 9 ve 10 satırlarda write sonucunun neden farklı olduğu ??

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 14, 2017
int[] a = [ 3, 5, 7, 8 ];
assert(remove(a, 1) == [ 3, 7, 8 ]);
assert(a == [ 3, 7, 8, 8 ]);

Bunun nedeni aslında remove asıl dizinin boyunu değiştirmiyor. Bunun yerine kırpılmış diziyi döndürüyor.

Buradaki örnekte birinci elemanı kapatalım. O zaman '3, 7, 8' dönecek. Kalan elemanlar da oluşan boşluğu doldurulacak şekilde bu örnekte 8 kaydırılıyormuş.

Bunun nedeni de 'std.algorithm' in sadece içeriği değiştirecek şekilde [yapıyı değil] tasarlanmış olması imiş.

Kısacası senin örneğinde şu şekilde kullanmak gerekiyor:

import std.stdio;
import std.algorithm;

void main(string[] argv)
{
   int[5] dizibes=[8,2,0,7,5];
   int[5] dizialti=[9,3,6,1,4];
   int[] dizitoplam=dizibes~dizialti;
   writeln("ikisini topladım ve sıraladım.....",sort(dizitoplam));
   dizitoplam = dizitoplam.remove(5);
   writeln("5.elemanı çıkarttım ve yazdırdım..",dizitoplam);
   writeln("Tekrar yazdırdım..................",dizitoplam);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 14, 2017

Burada başka bir etken daha var: Sabit uzunluklu dizilerin uzunluğu değiştirilemez. Yani, 'int[5]' her zaman için beş elemana sahip olacaktır.

Sabit uzunluklu dizilerle dilimlerin bellekteki durumları da çok farklı: Yukarıdaki sabit uzunluklu dizi, yan yana duran beş elemandan başka bir şey değil. Hatta, program yığıtında duruyor.

'dizibes''i gösteren bir dilim ise bellekte şu yapının eşdeğeridir:

   int[] dilim = dizibes;

/* 'dilim' iki üyeye sahiptir:
       size_t length; // Doğal olarak değeri 5'tir
       int* ptr;      // dizibes'in ilk elemanını gösteren göstergedir
*/

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 14, 2017

Bu durumda dizitoplam.remove(5)); ifadesi bir sonuç veriyor ama atama yapmayınca dizitoplam değişkeninden farklı netice çıkartıyor.. Bana elbetteki benden kaynaklanan sebeplerden dolayı çok saçma geliyor bu tam kavrayamıyorum.. Yine dediğim gibi ben aslında sizi anladığımı sanıyorum bahsettiğiniz kısımlardaki kaydırma ve dizi boyutunun değişmediğini de kavradığımı sanıyorum sadece sorunum şu write işlevinde yazan kısımlardaki aynı sonucu üretememe!!.. sonuç itibariyle benim mantığımda "dizitoplam.remove(5)); ifadesi bir sonuç doğurduğunda bu sonucu write ile yazdığımız vakit ile bir yerlere atadığımızda yazırdığımızla aynı olması lazım.. yada yukarda dediğim gibi ve sizinde anlatmak istediğiniz gibi aslında "dizitoplam.remove(5))" ifadesiyle, "dizitoplkam=dizitoplam.remove(5))" ifadesi aynı sonuçu üretmiyor.. Birazdaha kafa yorayım bakalım belki beynimi ikna ederim :)

Konuyla ilgili sizler kadar deneyimli olmamam sebebiyle sorularımdaki hatalar ve sizlerin uğraşılarınız için anlayışınıza sığınıyorum..
sevgiler saygılar..

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 15, 2017

Bu durumda Dilim ve Aralık kavramlarını birkez daha daha dikkatli okumak gerekiyor sanırım..

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 15, 2017

Ali ve Erdem bey tekrar merahabalar.. Dediklerinizi iyice okuyup bu seferde Visual Studionun memory watch seçeneğinden faydalanarak satır satır kodları işletip dizitoplam değişkenini inceledim.. Yine şaşırtıcı şeyler oldu açıkçası..
şimdi size satır satır yazayım,,
breakpoint koyduktan sonra 8.satırın işletimi bitti ve ben ordan aldığım memory resminde(kuvvetle muhtemel stack bölgesinde);
Name- Value
0-0
1-1
2-2
3-3
4-4
5-5
6-6
7-7
8-8
9-9
duruyor.. zaten konsoldada

ikisini topladım ve sıraladım.....[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

gözüküyor sorun yok bu beklediğimiz sonuç.. ardından 9. satırı işlettikten sonra bu stack alanındaki dizitoplam değişkeninin durumu;

Name- Value
0-0
1-1
2-2
3-3
4-4
5-6
6-7
7-8
8-9
9-9
yani aslında burda write ile yazdırdığımızda benimde beklediğim sonuç !! yani stackte de böyle.. oysa write ile yazdırdığımızda

5.elemanı çıkarttım ve yazdırdım..[0, 1, 2, 3, 4, 6, 7, 8, 9]

çıkıyor işte sorun burda başlıyor stack ayrı telden çalıyor write ile yazım ayrı :)

ve son olarak 10. satırı işletip stacke bağtığımızda;

Name- Value
0-0
1-1
2-2
3-3
4-4
5-6
6-7
7-8
8-9
9-9
yine yukarıdakiyle aynı ama u sefer write ile dizitoplamı yazdırdığımızda

Tekrar yazdırdım..................[0, 1, 2, 3, 4, 6, 7, 8, 9, 9]

buda beklediğimiz sonuç.. ama kafa karıştırıcı sonuç

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 15, 2017

Öncelikle, sabit uzunluklu dizilerle ilgili söylediklerim bu konuyla ilgili değilmiş çünkü remove() yapılan dizi sabit uzunluklu değil.

Alıntı:

>

Konuyla ilgili sizler kadar deneyimli olmamam sebebiyle sorularımdaki hatalar ve sizlerin uğraşılarınız için anlayışınıza sığınıyorum..

Dizi konuları D'de karışık olabiliyor çünkü sabit-dizilerle dilimler farklı hem de olayın içine aralık kavramı da giriyor. Seninle ilgisi yok. :)

Alıntı (cos00kun):

>

Bu durumda dizitoplam.remove(5)); ifadesi bir sonuç veriyor ama atama yapmayınca dizitoplam değişkeninden farklı netice çıkartıyor..

Evet. Bunun nedeni, std.algorithm.remove işlevinin bir aralık algoritması olması ve dizi olmayan topluluklarla da işleyebilmesidir. Diziden daha genel türlerle de işleyebildiğinden, eleman çıkartma işlemini, elemanları yer değiştirerek halleder. (Aynı gariplik C++'ın erişicilerle işleyen algoritmalarında da bulunur.)

Sabit uzunluklu dizi kullanıldığında gözlemler şaşırtıcı olabiliyor.

Alıntı:

>

aynı olması lazım

Sonucu aynı değişkene atayınca sorun kalmıyor:

   dizitoplam = dizitoplam.remove(5);

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 15, 2017

İki kavramı hatırlayalım:

  • Dizi: Yan yana duran (ve indeksle hızlıca erişilebilen) elemanlar topluluğu. Başka bir şey değil; örneğin, olayın içinde bunların ilkini gösteren gösterge ve hatta kaç adet oldukları bile yok.

Not: Evet, sabit uzunluklu dizilerin bile uzunlukları yok; çünkü uzunluk türlerinin parçası. Yani, uzunlukları derleme zamanında bilinen bir kavram ve çalışma zamanında değişmiyor.

  • Dilim: Yan yana duran elemanlara erişim sağlayan yapı; elemanların ilkini gösteren göstergeden ve eleman adedinden oluşuyor

Çoğu aralık algoritması gibi, remove() da çok kullanışlı olmak isteyen bir işlev. Bu yüzden, yalnızca dizilerle değil, kendisini BidirectionalRange olarak sunabilen her tür aralıkla kullanılabiliyor. BidirectionalRange hem başından hem de sonundan erişim sağlayan aralık demek. (Ek olarak, save() işlevi ile erişme durumunu da saklayabiliyor; yani, "save ettiğim yerden devam edeyim" diyebiliyor.)

remove() şöyle işliyor:

  1. Baştan başlayayım

  2. Bildirilen indekse gelince durayım

  3. O indeksteki elemanı çıkartmış olmak için sonuncu elemanı onun üstüne kopyalayayım indekse yerleştireyim (Aslında bu davranışı değiştirebiliyoruz; aşağıda açıklıyorum)

  4. Bir eleman eksilmiş olsun diye (ve tabii o sonuncu eleman iki kere tekrarlanmasın diye) sonuç olarak döndüreceğim aralığı son taraftan bir azaltayım

Yani, silme işlemi asıl elemanların dizi olduklarını bilmeden ve elemanları bir yerden başka yere taşıyarak gerçekleştiriliyor. Dolayısıyla, asıl elemanlar bu örnekteki gibi dizi olduklarında asıl dizide tekrarlanan elemanlar oluyor. (Bu örnekteki sondaki 9 gibi.)

Anlattığım algotirmanın bu örneğe uymadığının farkındayım çünkü ben eleman değiştirme kararınını daha kolay anlatayım diye 'SwapStrategy.unstable' olarak düşündüm. Oysa, varsayılan karar 'SwapStrategy.stable''dır. stable, elemanların sıralarının korunması, unstable ise korunmaması anlamına gelir.

unstable daha hızlı tek kopyalama yetiyor: 3 numaralı adımda sondaki elemanı belirtilen indekse kopyaladık ve işimiz bitti. stable olsaydı, belirtilen indeksten sonraki bütün elemanları teker teker bir sola kaydırmak gerekirdi. Çok daha fazla eleman kopyalardık ama sonuçta eleman sıralarını korumuş olurduk. Programcı ne istediğine karar verebiliyor. Aynı programı bir de unstable ile çalıştıralım:

   writeln("5.elemanı çıkarttım ve yazdırdım..",dizitoplam.remove!(SwapStrategy.unstable)(5));

Bu sefer sondaki elemanın (yani, 9'un) belittiğimiz indekse gittiğini görüyoruz:
'
5.elemanı çıkarttım ve yazdırdım..[0, 1, 2, 3, 4, 9, 6, 7, 8]
Tekrar yazdırdım..................[0, 1, 2, 3, 4, 9, 6, 7, 8, 9]
'

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 17, 2017

Çok açıklayıcı oldu sağolun.. Benim kafamı karıştıran kısım D dilinde dilimler, bazı işlevler yada bazı niteliklerin aslında referans gibi çalışabileceğini ve davranabileceği konusunu idrak edememdi sanırım.. Yine konumuza dönersek burada temel nokta şu dizitoplam.remove(5)) aslında eşit değildir dizitoplam=(dizitoplam.remove(5) in sonucuna çıkıyor Write işlevine sokunca
Yinede
writeln(dizitoplam.remove(5)) ile writeln(dizitoplam=writeln(dizitoplam.remove(5)) eşit sonuç üretseydi hiç fena olmayacaktı :)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 17, 2017

off offf ;-) aslında benim için iyi bir beyin jimnastiği sizin içinde sanırım biraz eziyet oldu ama sonunda soru işaretsiz olarak konuyu anladığımı sanıyorum.. bu topic boyunca anlayamadığım ve şimdi tam olarak anladığım sanırım şu dizitoplamın elemansayısı 10 olduğundan yığıtta 10 adet elemanı göstermesi oysa remove yi direk write da kullanınca haklı olarak dizitoplamdan 1 eksik eleman yazdırması.. tam doğru ifade edebildimmi bilemiyorum ama en azından çelişen hiç bir durum kalmadı kafamda ... tekrar sağolun Ali ve Erdem hocam...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2