Jump to page: 1 2 3
Thread overview
Girişten tek tek sayı okumak
Sep 17, 2012
erdem
Sep 17, 2012
erdem
Sep 17, 2012
Salih Dinçer
Sep 17, 2012
erdem
Sep 18, 2012
erdem
Sep 18, 2012
erdem
Sep 18, 2012
erdem
Sep 19, 2012
Salih Dinçer
Sep 19, 2012
erdem
Sep 20, 2012
erdem
Sep 20, 2012
erdem
Nov 06, 2013
erdem
Feb 18, 2016
erdem
Sep 20, 2012
Salih Dinçer
September 17, 2012

Girişten sayıları okuyan bu sınıfın D sürümünü yapmaya çalışıyorum.

http://introcs.cs.princeton.edu/java/stdlib/StdIn.java.html

Bunu kullanan örnek şu şekilde:

       while (!StdIn.isEmpty()) {
           int p = StdIn.readInt();
           int q = StdIn.readInt();
           /*  ... */
       }

Şimdi burada dikkat ederseniz, giriş boş olmadığı sürece girişten okuyor. Aynı zamanda 'readInt()''de sadece bir tane tamsayı döndürüyor.

Programı kullanırken de 'java programadı < giriş.txt' şeklinde girişten verileri okuyor. Örnek bir giriş dosyası da bu şekilde:

10
4 3
3 8
6 5
9 4
2 1
8 9
5 0
7 2
6 1
1 0
6 7

D ile bu şekilde bir Giriş sınıfı yazsak buradaki bilgilere göre bir kuyruk mu kullanmamız gerekir.

import std.stdio;

class BB
{
	private:
		int[] no;
		int[] boyut;
		int kaçTane;

	public:
		this(int N)
		{
			assert(N >= 0);
			kaçTane = N;
			no = new int[N];
			boyut = new int[N];
			for (int i = 0; i < N; ++i) {
				no[i] = i;
				boyut[i] = i;
			}
		}
}
void main()
{
	BB bb = new BB(10);
}

Bir de örneğin bu sınıfta 'no = new int[N];''in esprisi nedir.

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

September 17, 2012

Tabi bu kodu incelediğimde aslında bu sınıfın 'java.util.Scanner' sınıfını saran basit bir sınıf olduğunu gördüm.

Ama scanner sınıfı oldukça yetenekli. Örneğin girişten bilgi okuyabiliyor:

    Scanner sc = new Scanner(System.in);
    int i = sc.nextInt()

Ya da bir dosyadan da okuyabiliyor.

     Scanner sc = new Scanner(new File("myNumbers"));
     while (sc.hasNextLong()) {
         long aLong = sc.nextLong();
     }

İşin ilginci karışık olarak dosya içinde bulunan sayısal ve dizgi değerlerini ayırt edebiliyor.

    String input = "1 fish 2 fish red fish blue fish";
    Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
    System.out.println(s.nextInt());
    System.out.println(s.nextInt());
    System.out.println(s.next());
    System.out.println(s.next());
    s.close();

Çıktısı:Alıntı:

>
 1
 2
 red
 blue

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html

Ya da hiç bu sınıfla uğraşmadan bildiğimiz 'readf' ile dosyadan okutsamıydık.

Sanırım benden önce başka birisi de (http://lists.puremagic.com/pipermail/digitalmars-d/2011-May/101586.html) böyle bir girişimde bulunmuş.

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

September 17, 2012

Bu konuda şu başlıkta (http://ddili.org/forum/thread/800) şöyle bir döngü kurmuştum:

   char oku;
   while (true) {
       write("=: ");
       do {
           readf("%s", &oku);
           // enter(10)'a basılana kadar okumaya devam et...
       } while (oku!=10);
   }

Belki işe yarar çünkü proje kimsenin ilgisini çekmemişe benziyordu. Bu başlığı da silip atsak mı?

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

September 17, 2012

Ali bey açıklamalar çok yardımcı oldu teşekkürler. Şimdi örnekleri inceliyorum.

Bu arada dikkat ediyormusunuz bilmiyorum konular çok ilginç noktalara gidiyor.

Salih'cim ben de tüm mesajların yararlı olduğunu düşünüyorum. Ama hepimizin ilgisini çeken farklı konular olduğu için açıkçası bazen ben bazı mesajları es geçiyorum. Okuyorum mesajları ama ilgimi çekmezse satır satır derlemiyorum :blush:

Ama diğer taraftan senin yazdığın programların çoğunu deniyorum. Hatta geçenlerde @Kadir Can (http://ddili.org/forum/user/50)'ın kulakları çınlasın. Yazdığı Huffman algoritmasıyla ilgili bir program vardı. Ben de daha önceden bu algoritmayı bilmiyordum.

Haftasonu çalışıp öğrendim :)

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

September 17, 2012

(Aşağıdakileri senin yanıtını görmeden yazmışım.)

Alıntı (erdem):

>

Girişten sayıları okuyan bu sınıfın D sürümünü yapmaya çalışıyorum.

http://introcs.cs.princeton.edu/java/stdlib/StdIn.java.html

Önce hatırlıyorum: Standart giriş bir karakter akımıdır. (Senin bunları bildiğinden neredeyse eminim ama yine de duramadım ve yazdım. :))

O sınıf asıl işlerini java.util.Scanner'a yaptırıyor. Scanner (galiba) düzenli ifadelerden anlayan bir akım ayrıştırıcıymış.

Phobos'ta bu kavramlara yakın olarak std.format ve bir de emekliye ayrılacak olan std.cstream var. (std.format.formattedRead'i aşağıda kullandım.) Bunlara ek olarak, aralık kavramını destekleyen bir çatı düşünülüyor ama temeli karakterlere (ve hatta UTF-8 kodlarına) dayandığı için bunun tam olarak çözülebileceğini sanmıyorum.

Örneğin, int okunmasını istediğimizde girişte "ab" varsa hata kabul edilir ama "1abc" varsa 1 int olarak okunur.

Akımlarda okuma ve yazma birbirinin karşıtı da olamaz. İki int'i 10 ve 20 olarak yazsak okurken 1020 diye tek int olarak okumak zorundayızdır.

Bu tür garipliklerin bir örneği, gösterdiğin sınıfın da içine düştüğü "true", "1", "false", ve "0" dizgilerinin bool değerler olarak kabul edilmeleridir. Ya o 1 ve 0 yanlışlık sonucu araya girmiş int iseler? Yani, program içinde sıfır olmayan değerler true anlamına geliyorlar ama dosyaya 42 diye yazılmış iseler true diye okunamıyorlar. Çelişkili.

Umarım bunlar karakter akımlarının güçlüklerini göstermeye yetiyordur.

Alıntı:

>

Bunu kullanan örnek şu şekilde:

>         while (!StdIn.isEmpty()) {
>             int p = StdIn.readInt();
>             int q = StdIn.readInt();
>             /*  ... */
>         }
> ```

>
> Şimdi burada dikkat ederseniz, giriş boş olmadığı sürece girişten okuyor. Aynı zamanda readInt()'de sadece bir tane tamsayı döndürüyor.

Programların standart girişlerine bağlı olan karakter akımlarının kaynağının durumu program tarafından bilinemez. Örneğin "daha 5 karakter" kaldı gibi bir bilgiyi program edinemez. Bunun nedeni, standart girişin (çoğu durumda olduğu gibi) konsola da bağlı olabileceğidir. Konsolda oturan kişinin de girişi hemen mi sonlandıracağı yoksa daha on sayfa yazdıktan sonra mı kapatacağı bilinemez.

Alıntı:
>
> Programı kullanırken de java programadı < giriş.txt şeklinde girişten verileri okuyor.
>

O durum biraz daha iyi gibi görünebilir çünkü giriş bir dosyaya bağlı. Ama yine de yeterli değildir çünkü program yine de bir karakter akımı olarak görmek zorundadır. Programın girişinde "sana 100 karakter veriyoruz" diye bir arayüz yoktur.

Ek olarak, konsol durumundaki klavyenin iç karakter belleği de dahil olmak üzere arada birden fazla ara bellek bulunabilir. Bunlar etkinlik adına bilgiyi programa belirli büyüklükteki parçalar halinde veriyor olabilirler. Örneğin bazı katmanlar ancak satır sonu karakteri gördükçe bilgiyi satır satır aktarırlar.

İşte o yüzden girişin sonuna gelinip gelinmediği ancak ve ancak girişten karakter okumaya çalıştıktan sonra ve o okuma başarısızlıkla sonuçlanmışsa ve o başarısızlık bir hata nedeniyle değil ise anlaşılabilir.

Yeni başlayanların (ve deneyimlilerin de :)) içine düştükleri bir hata:


import std.stdio;

void main()
{
auto dosya = File("deneme_dosyasi");

while (!dosya.eof) {
int i;
dosya.readf(" %s", &i);
writeln("okudum: ", i);
}
}



deneme_dosyasi'nın içinde "1 2 3" satırı bulunduğunu düşünelim. Ama sonda bir tane de boş satır olsun. Nasıl olsa o satırı yazıp sonunda Enter'a basmak ve kaydetmek yaygın bir davranıştır. Öyle yapıldığında program dört int okur (!): 1, 2, 3, ve 0. :p

Doğrusu, readf ile int okumaya *yeltendikten* sonra kaç dönüşümün başarılı olduğuna bakmaktır:


   immutable dönüşümAdedi = dosya.readf(" %s", &i);
   if (dönüşümAdedi == 1) {
       writeln("okudum: ", i);
   }


Veya eof tekrar denetlenebilir:


   if (!dosya.eof) {
       writeln("okudum: ", i);
   }


Bütün bunlara bakarak, Scanner'ın girişin boş olup olmadığı kavramı için girişten önceden karakterler toplamış olduğunu ve isEmpty() kavramı için elinde karakter bulunup bulunmadığına baktığını düşünebiliriz.

Alıntı:
>
>  Örnek bir giriş dosyası da bu şekilde:
>
> 10
> 4 3
> 3 8
> 6 5
> 9 4
> 2 1
> 8 9
> 5 0
> 7 2
> 6 1
> 1 0
> 6 7
>
> D ile bu şekilde bir Giriş sınıfı yazsak buradaki bilgilere göre bir kuyruk mu kullanmamız gerekir.

Olur ama şart değil. Tabii ki okudukça dizinin sonuna eklenebilir. Dikkat edersen onlar da bu sınıfa readInts() diye bir işlev eklemişler. O işlev girişin *geri kalanını* int'ler olarak okuyor. Ne yazık ki, readInts() de girişten okumanın güçlüğünün başka bir göstergesi: Yani bir dizi int ancak en sonda gelebiliyor. :( (Arada okumaya kalksak kendisinden sonra gelen ve olasılıkla diziye ait olmayan int'leri veya int olabilecek karakterleri de okurdu.)

Alıntı:
> Bir de örneğin bu sınıfta no = new int[N];'in esprisi nedir.

no'yu istersen boş olarak oluşturup okunan int'leri onun sonuna ~= ile de ekleyebilirsin. Öyle yaptığında dizi büyüdükçe yeni yer ayrılması ve elemanların kopyalanmaları gerekecektir. Eğer baştan kaç tane olduğunu bilirsen 'new int[N]' ile hepsi için o kadarlık yer ayırıyorsun. Ama aslında N adetlik gerçek bir dizi oluşuyor. Yani bütün elemanları yasaldır. Eğer bütün amaç bellekte yeni yer(ler) ayrılmasını önlemek ise std.array.reserve ile N adetlik yer de ayrılabilirdi. (Veya geçende de konuştuğumuz gibi, std.array.Appender da kullanılabilirdi.)

Ama şunu da düşünmek gerek: bütün int'leri okuyup bir diziye yerleştirmek şart mı? Yani o int'leri ancak ondan sonra mı kullanacağız? Eğer şart değilse, yani int'ler okundukça işlenebiliyorlarsa bu işi tembel olarak da halledebiliriz. byLine() File'ın içeriğini satır satır gösterir.

Ama dikkat: hızlı olsun diye hep içinde tuttuğu aynı string'i kullanır. Yani 'satır'ı doğrudan bir diziye yerleştiremezsiniz. satır.dup (veya satır.idup) ile kopyasını almak gerekir.

Benim aşağıda satırın kopyasına ihtiyacım yok:


import std.stdio;
import std.format;
import std.array;

void main()
{
foreach (satır; stdin.byLine()) {
while (!satır.empty) {
int p;
int q;

       immutable dönüşümAdedi = formattedRead(satır, " %s %s", &p, &q);

       if (dönüşümAdedi != 2) {
           writefln("Çift int bulamadım. :(");

       } else {
           writefln("p: %s, q: %s", p, q);
       }
   }

}
}



Son olarak, bu Java sınıfının bir benzerini ddio.d ismiyle yazmaya başlamıştık. Forumda aratabilirsin. O sınıfın temeli şuradaki sayıOku() işlevine dayanıyor:

 http://www.ddili.org/ders/d/islevler.html

Ali

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

Alıntı (Salih Dinçer):

>

Bu başlığı da silip atsak mı?

İlgi çekmediği konusuna kesinlikle katılmıyorum. Forumlar kalıcıdır. Bugün hiçbir kimsenin ilgisini çekmese bile yazıldığı an birisinin ilgisini çekmiştir ve gelecekte sonsuz sayıda kişinin ilgisini çekebilir.

Hiç kimsenin ilgisini çekmemiş bile olsa, hayır, silmeyelim.

Ali

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

September 18, 2012

Programı yazdım:

import std.stdio;
import std.format;
import std.array;
import std.conv;

class BB
{
   int bağ[];
	int uzunluk[];
	int kaçTane;

	public:
	    this(int N)
		{
		    assert(N >= 0);
			kaçTane = N;
			bağ = new int[N];
			uzunluk = new int[N];
			for (int i = 0; i < N; ++i) {
				bağ[i] = i;
				uzunluk[i] = 1;
			}
		}

		int bul(int p)
		{
			assert(p >= 0 && p < bağ.length);
			while (p != bağ[p])
				p = bağ[p];
			return p;
		}

		int say()
		{
			return kaçTane;
		}

		bool bağlıMı(int p, int q)
		{
			return bul(p) == bul(q);
		}

		void bağla(int p, int q)
	    {
			int i = bul(p);
			int j = bul(q);
			if (i == j) return;

			if (uzunluk[i] < uzunluk[j]) { bağ[i] = j; uzunluk[j] += uzunluk[i]; }
			else                         { bağ[j] = i; uzunluk[i] += uzunluk[j]; }
			--kaçTane;
		}
}
void main()
{
	int N;
	readf(" %s", &N);
	BB sayılar = new BB(N);

	foreach (satır; stdin.byLine()) {
		while(!satır.empty) {
			int p;
			int q;
			immutable okunanSayılar = formattedRead(satır, " %s %s", &p, &q);

			if (okunanSayılar != 2) {
				writeln("Çift int bulamadım");
			} else {
				if (sayılar.bağlıMı(p, q)) continue;
				sayılar.bağla(p, q);
				writefln("%s %s", p, q);
			}
		}
	}

	write(sayılar.say(), " tane bagli kume");
}

Şöyle çalışıyor:

  • Girişten nesne sayısını N oku
  • Tekrarla:
    ** Girişten bir çift tamsayı oku
    ** Eğer bağlı değillerse bağla ve bağlı çiftleri ekrana yaz.

Örneğin giriş dosyamız şu şekilde olsun:

10
4 3
3 8
6 5
9 4
2 1
'8 9'
5 0
7 2
6 1
'1 0
6 7'

Bu durumda zaten birbirine bağlı olan yeşille gösterilen kısımları ekrana yazmıyoruz.

Bunu grafiksel olarak gösterirsek programın çalışması şu şekilde:

http://algs4.cs.princeton.edu/15uf/images/dynamic-connectivity-tiny.png

Programın en sonunda da birbirine bağlı küme sayısını yazdırıyoruz. Bu durumda 2 olmuş oluyor:

{0 1 2 5 6 7} ve {3 4 8 9}

Programı çalıştırmak için 'program < giriş.txt' yazmanız yeterli.

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

September 18, 2012

Denemek için içerisinde 11 bağlantı olan küçük metin (http://algs4.cs.princeton.edu/15uf/tinyUF.txt) dosyasını, içerisinde 900 bağlantı bulunan orta büyüklükteki (http://algs4.cs.princeton.edu/15uf/mediumUF.txt) metin dosyasını ve içerisinde milyonlarca bağlantı bulunan (http://algs4.cs.princeton.edu/15uf/largeUF.txt)bu dosyayı kullanarak Java ve D test sonuçlarını karşılaştırdım.

Java sonuçları:

'real 0m48.481s
user 0m25.698s
sys 0m13.109s
'

D bir kaç saniye ile öne geçti ;)

'599490 768644
394023 336525
203886 174275
6 bileşen

real 0m41.939s
user 0m18.021s
sys 0m11.749s'

Geçen süreyi hesaplamak için time komutunu kullandım:

'time ./test < largeUF.txt '

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

September 18, 2012

Bir saniye farketti ;)

Evet haklısınız.

Bu arada ben çok yavaş gidiyorum. Satır satır bazen ne yaptığını anlamaya çalışıyorum. Zaten geç kalmışım. Finaller başlamış bile. Ama önemli değil sonra tekrar alırım.

Bu arada Algorithms kitabını henüz incelemediyseniz D Programlama Dili kitabını çıkartmadan önce incelemenizi tavsiye ederim. Hem içerik hem sunuş biçimi gayet güzel. Bir de internet üzerinden derslerle birleşince harika olmuş. Örneğin ufak bir grafik kütüphanesi yazmışlar. Böylece öğrenciler sıralama algoritmalarının sonuçlarını ve nasıl çalıştığını grafiksel olarak görme imkanı buluyorlar.

Demek istediğim böylece ilginç fikirler oluşabilir.

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

September 18, 2012

Bu problemi hatırlıyorum. :) Kitap bu bağlama problemini önce bir güzel böyle yaptırır. Sonra bunun ne kadar yavaş bir algoritma olduğunu gösterir. Hızlı algoritmayı görünce öğrencinin ağzı açık kalır ve algoritmaların ne kadar önemli olduklarını anlamış olur. :)

Ali

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

« First   ‹ Prev
1 2 3