Yazan: Şadi Evren ŞEKER

Fonksiyonlar tekrarlama yapılarına göre temel olarak iki türlü düşünülebilir. Buna göre bir fonksiyonun içinde yine kendisinden bir parça bulunuyorsa bu fonksiyonlara özyineli (recursive) fonksiyon denilirken, fonksiyonun kendisini tekrar etmemesi durumunda döngülü (iterative) fonksiyon ismi verilir.
Teorik olarak bütün döngülü (iterative) fonksiyonlar özyineli (recursive) fonksiyon olarak yazılabilir (tersi de doğrudur).
Öreğin 1’den verilen sayıya kadar olan sayıları toplayan bir fonksiyonu hem özyineli hem de döngülü olarak yazalım:

//özyineli olarak:
int topla(int a){
  if(a==1)
    return 1;
  return a+ topla(a-1);
}
//döngülü olarak
int topla(int a){
  int toplam= 0;
  for(int i = 0 ;i
    toplam= toplam+a;
  }
  return toplam;
}

Dikkat edilirse ilk foksiyonun içerisinde kendisini çağıran bir satır bulunmaktayken ikinci fonksiyonda çözüm bir döngü yardımı ile (for döngüsü) yapılmıştır.

Ekrana 1’den 10’a kadar olan sayıları bastıran kod (Fatih Bey’in sualine cevaben)

Örneğin ekrana 1’den 10’a kadar olan sayıları bastıran bir kod yazmak isteyelim. Kodu özyineli (recursive) bir fonksiyonla yazdıralım ve kullanıcı aslında ekrana kaça kadar basılmak istediğini fonksiyona parametre olarak geçirsin (bu soruda 10 olacak)

Aşağıdaki kodu ele alalım:

Yukarıdaki kodun çalışan hali aşağıda verilmiştir:

Görüldüğü üzere kod ekrana 1’den 10’a kadar olan sayıları bastırmıştır.

Burada ekrana bastırma işlemini yapan fonksiyon koddaki 4-8 satırlar arasında tanımlı olan f() fonksiyonudur. Fonksiyon bir n değerinden başlayarak ekrana anlık olarak n değerini bastırmış ve her adımda n-1 değeri ile fonksiyonu tekrar çağırmıştır.

Şayet yukarıdaki şekilde bir if kontrolü ile çağırmayı engellemek yerine her adımda kendisini tekrar çağırmasını isteseydik aşağıdaki şekilde kodu yazabilirdik:

Kodda görüldüğü üzere özyineli olarak fonksiyonun kendisini çağırması işlemi ve ekrana printf fonksiyonu marfietiyle yazma işlemi aynı sırada verilmiştir. Ancak fonksiyonun bitişini belirten if kontrolü, n değerinin 0 olması durumunda return 0; yaparak işlemi durdurmuştur.

Burada return 0 yapılmasının veya return 1234 yapılmasının bir önemi yoktur, fonksiyon herhangi birşey return ederek artık bittiğini belirtmektedir.

Yukarıdaki kod benzer şekilde return void yapacak halde yani integer bir değer döndürmeyecek halde yeniden yazılabilir:

Yukarıdaki kodun yeni halinde fonksiyonun döndürdüğü değer tipi int yerine void haline gelmiştir. Bunun sebebi aslında fonksiyonun geri değer döndürmüyor oluşudur. Ayrıca fonksiyondaki 6. satırda return teriminden sonra bir değer bulunmaz, yani sadece return edilir ve fonksiyon nihayete erer.

Yukarıdaki bu özyineli fonksiyonlarda 3 temel unsur her zaman dikkate alınmalıdır:

  • başlangıç değeri
  • bitiş değeri
  • adım değeri

Yukarıdaki basit 1’den 10’a kadar olan sayıları basan kodda başlangıç değeri 10 olarak kullanıcı tarafından veriliyor. Ayrıca özyineli devam işlemi 0’a ulaşınca bitiyor. Bunu kontrol eden bir if kodun ilk satırında bulunuyor. Kodun her adımında n-1 değeri fonksiyona yeniden veriliyor. Bu değer de adım değerini oluşturuyor.

Örneğin yukarıdaki fonksiyonu yine özyineli bir görüntü altında iteratif olarak yazabiliriz. Bu yazılış şekline geçiş tarzı şekli (continuation by passing style) ismi verilir:

Yukarıdaki kodun yeni halinde, 12. satırd bulunan f fonksiyonuna dikkat edilirse, 10’a kadar olan sayılar 1’den başlanarak basılsın diye iki ayrı parametre verilmiştir. Fonksiyonumuz i değerini her adımda arttırmakta ve n değerine eşit olunca durmaktadır. Durma işlemi yine bir önceki fonksiyonda olduğu üzere void değer return edilerek olmaktadır.

Yukarıdaki kod aslında iteratif bir koddur, bunun sebebi fonksiyonlardan herhangi birisinin çalışması için kendi içerisinden çağırdığı f(n,i+1) fonksiyonun çalışması beklenmemektedir. Ancak döngü ile yazılmış bir fonksiyondan da farkldır.

Ekrana Yıldızlar kullanılarak X harfi basan kod (Duygu Hanımın talebi üzerine ekliyorum)

Amacımız ekrana aşağıdaki şekilde bir X harfi basmak olsun:

*   *
 * * 
  *
 * *
*   *

Yukarıda görülen şekil kullanıcıdan 5 girişi için çizilen şekildir. Bizim amacımız bu şekli çizen bir kodu özyineli (recursive) fonksiyonlar marifetiyle ekrana çizdirmek.

Yukarıdaki şekil 2 boyutlu bir şekil olduğu için hem satır hemde sütun boyutlarında işlem yapmamız gerekiyor. Öncelikle satır boyutunda çözüm üretip sonra bu satır işlemini tekrarlayan bir işlemle şekli çizdirebiliriz.

Satırlara dikkat edilirse her satırda 2 yıldız ve 3 boşluk bulunuyor. Bu durum nxn boyutunda bir x harfi için n-2 boşluk ve 2 yıldız olarak formüllenebilir.

Yukarıdaki X harfinde dikkat edilirse bir karenin iki köşegeni * diğer değerler ise boşluk olarak çizilmiştir. Bu durumda karenin köşegenlerini nasıl bulacağımızı düşünürsek, satırları tutan bir i değişkeni ve sütunları tutan bir j değişkeni için i==j ve i==n-j durumlarında köşegen değerleri bulunduğu görülür.

Bu durumu aşağıdaki i ve j indislerinin yazılı olduğu tabloda görebiliriz:

i,j 1 2 3 4 5
1 1,1 1,2 1,3 1,4 1,5
2 2,1 2,2 2,3 2,4 2,5
3 3,1 3,2 3,3 3,4 3,5
4 4,1 4,2 4,3 4,4 4,5
5 5,1 5,2 5,3 5,4 5,5

Yukarıdaki tablodan da anlaşılacağı üzere her satır için bulunduğumuz satır numarası (i) ve karenin boyutu- satır numarası (n-i) koordinatlarına * sembolü koyuyoruz. Bunu yapan bir özyineli fonksiyonu (recursive function) aşağıdaki şekilde kodlayabiliriz:

Yukarıdaki kodda, n kullanıcının girdiği ve X harfinin boyutlarını tutan değişken, i satır, j ise sütun sayısı olmak üzere kodun 5. satırında bulunan if döngüsü i ve j ikilisinin köşegen olup olmadığını kontrol etmektedir. Şayet köşegen olan bir hücre ise * koymakta diğer durumlarda da boşluk koymaktadır.

Yukarıdaki fonksiyon her satır için yeniden çalışmakta ve n+1 değerine ulaştığında hiçbir işlem yapmadan nihayete ermektedir.

Yukarıdaki yeni fonksiyon, ilk fonksiyonu n kere çağırmakta ve her çağırma işleminde satır sayısı olan i değişkeninin değerini 1 arttırmaktadır. Böylelikle ilk fonksiyonumuz hangi satır için yazma işlemi yaptığını bilmektedir.

Yukarıdaki iki fonksiyonu birleştirip main fonksiyonu ekleyince aşağıdaki şekilde olur:

Kodun çalışan hali ise aşağıda verilmiştir:

Bir dizgiden (String) boşlukları temizleyen kod

Gelen bir soru üzerine bir dizgideki (string) boşlukları temizleyen kodu yazıp yayınlıyorum:

Kodu kısaca anlatacak olursak. Öncelikle boslukTemizle fonksiyonumuzun üç farklı durum için kodlandığını söyleyebiliriz.

1. parametre olarak verilen dizgi boş olabilir. Bu durumda dizgi göstericimizin gösterdiği değer, dizgi sonu olan karakteridir (end of string). Bu kontrol farklı şekillerde de yapılabilir. Örneğin if(strlen(dzgi)==0) kontrolü de dizginin sonuna geldiğimizi anlatır. Dizgi boşsa veya özyineli fonksiyonumuz marifetiyle, dizginin sonuna kadar geldiysek, yine boş bir dizgi döndürerek bu durumu çözüyoruz.

2. parametre olarak verilen dizginin ilk karakteri boşluk karakteridir. Bu durumda, bu karakterin sonuçta bulunmaması gerekir ve dolayısyla bu karakter atlanarak fonksiyonumuz özyineli bir şekilde çağırılır ve işlenmeye devam eder. Yine çeşitlilik olması açısından buradaki kontrol de if(strncmp(dizgi,” “,1)) şeklinde yapılabilir.

3. parametre olarak verilen dizgi, yukarıdak iki durum dışında bir karakter ile başlıyordur. Bu durumda dizginin sonraki karakterlerine bakılması için dizginin ilk karakteri dışındaki karakterleri yeniden fonksiyona verilir. Ancak çıkan sonucun başına, şu andaki karakter eklenir. Dolayısıyla dizginin geri kalan elemanları, yeniden verildikleri fonksiyonun içerisinden, boşlukları temizlenmiş olarak dönecek ve şu anda bakılan karakter bu dönen dizginin başına eklenecektir.

Yukarıdaki kodda, dizgi fonksiyonlarını string.h kütüphanesinden ekleyerek kullandım ve parametremiz olan dizgiyi bir dizgi (string) gibi muamele ettim 🙂 elbette bu parametreye bir dizi (array) gibi muamele etmek de mümkündür ve bu durumda mantık aynı kalmakla birlikte kodlama biraz değişecektir.

Yukarıdaki şekilde, kodun çıktısı da görülmektedir. Kodu Pardus 2011 altında gcc ile test ettim ve hatasız çalışıyor, diğer ortamlarda da sorunsuz çalışacağını tahmin ediyorum.

 


int yildiz2(int n,int i,int j){

if(j==n+1)

return -1;

if((i+j)==n+1 || i==j)

printf(“*”);

else

printf(” “);

yildiz2(n,i,j+1) ;

}

Yorumlar

  1. fatih
    int f(int a){
        if(a==11){
                  return -1;
                  }
    }
    

    hocam recursive fonksiyonda diyelimki 1 den 10 a kadar sayıları yazmak istersek,bu bolumdeki kod return -1 in gorevi nedir? aynı bolumde if a=10 oldugunda neden 10 u dahil etmez?Burdan anlayacagımız return 0 -1 ve 1 in gorevleri farklımıdır?

  2. duygu

    Mrb hocam recusive olarak yazılan yıldız sorusu kdunu tam olarak anlayamadım daha kolay anlayabilmem için bir kaç ipucu verebilirseniz sevinirim şimdiden teşekkürler.

    int yıldız2(int n, int i,,int j){
    if(j==n+1)
    return-1;
    if((i+j)==n+1|| i==j)
    printf("*");
    else
    printf(" ");
    yıldız2(n,i,j+1);
    }
    int yıldız(intn, inti){
    if(i==n+1)
    return-1;
    yıldız2(n,i,1);
    printf("n");
    yıldız(n,i+1);
    }
    int main(){
    printf("bir sayı giriniz")
    int n;
    scanf("%d",&n);
    yıldız(n,1);
    getch();
    }
    
  3. efes

    merhaba;
    kendim recursive olarak fibonacci yazmak istedim sadece girilen değerin sonucunu ekrana çıkartıyor nerede eksiklik var ?

    #include 
    #include 
    int fib(int n){
        if(n==0||n==1){
                       return 1;
                       }
                       return fib(n-1)+fib(n-2);
                       }
                       int main(){
                           int n;
                           printf("fibonacci icin bir sayi giriniz");
                           scanf("%d",&n);
                           printf("%d",fib(n));
                           getch();
                           return 0;
                           }
    
  4. Ahmet
    void yaz(int k) {
         
         printf("k:%dn",k);
         k++;
         if(k>3) 
         return ;
         yaz(k);
         yaz(k);
         }
    

    Bu kodda k sırasıyla 1 2 3 sayılarını bastıktan sonra 4 olacak ve return edecek(ben oyle biliyorum).Fakat ikinci yaz fonksiyonuna nasıl ugruyosa ve nasıl oluyosa sırasıyla 3 2 3 3 bu degerlerde basılıyo ve programdan cıkılıyor.ben özyinelemeli algoritmalarda boyle ust uste aynı fonksiyon cagırılınca sıkıntı yasıyorum.Yukarıdaki su kod neden 1 2 3 ü bastıktan sonra 4 olunca programı tamamlamıyor ?

  5. Şadi Evren ŞEKER Article Author

    Bakın bir kodun özyineli (recursive) olması, çalışmasını hiç etkilemez. Sizin verdiğiniz örnekte, fonksiyon iki kere kendisini çağırmış. Dolayısıyla normale kendisini değil farklı bir fonksiyonu iki kere çağırdığınızda nasıl çalışırsa aynen o şekilde çalışır.

    Örneğin:

    f(){
     g();
     g();
    }
    

    şeklinde kodlanan bir “f” fonksiyonu, “g” fonksiyonunu iki kere çağırır ve çalıştırır.

    Dolayısıyla

    f(){
     f();
     f();
    }
    

    şeklinde kodlanan bir fonksiyonda aynen benzer şekilde 2 kere kendisini çalıştırır.

    Gelelim gerçek bir örneğe. Sizin kodunuzu tahlil edelim:

    void yaz(int k) {
    
       printf(“k:%dn”,k);
       k++;
       if(k>3)
          return ;
       yaz(k);
       yaz(k);
    }
    

    C, bu kodu her zaman olduğu gibi, satır satır çalıştıracaktır. Örneğin k=1 parametresi ile yaz(1) şeklinde main fonksiyonundan çağrıldığını düşünelim. Bu durumda satır satır çalıştırıyoruz.

    1. printf satırı ekrana k değerini yani 1 basıyor
    2. k++ satırı ile k değeri 1’den 2’ye çıkıyor (yerel değişken, local variable)
    3. k değerinin 3’ten büyük olup olmadığı kontrol ediliyor ki şu andaki değeri 2 ve bu if’e ve sonrasındaki return satırına girmeden atlıyoruz.
    4. yaz(k) satırı çalışıyor ve kodumuz buraya geri dönmek üzere bir işaret koyuyor ve yaz fonksiyonunu yeniden çalıştırmaya başlıyor.

    Bakın burası önemli, yani kodumuz yaz(2) fonksiyonunun işini bitirdikten sonra bu satırdan, yani kaldığı yerden devam edecek. Buraya yazının ilerleyen aşamalarında döneceğim için * işareti koyuyorum.

    Kodumuz bu defa yaz(2) işlemini yapacak yine benzer şekilde ekrana 2 yazıyor, ardından 1 arttırıp yaz(3) işlemini çalıştırıyor yine geri döneceğim için ** işareti koyuyorum.

    bu defa kodumuz yaz(3) işlemini yapıyor ve ekrana 3 basıp ardından k değerini 1 arttırıyor k=4 olduğu için if koşulu sağlanıyor ve return ediliyor.

    Bakın buradaki return bizim fonksiyonumuzun bittiğini gösteriyor, dolayısıyla iki önemli şey oluyor:

    1. kodun bundan sonrası çalıştırılmıyor yani yaz(4) şeklinde gelen satırlar çalışmayacak
    2. kod, çağrıldığı yere return ediliyor (geri dönüyor)

    peki bu fonksiyonu nereden çağırmıştık? yazıdaki ** işaretli yerden. Burada bir adet daha yaz(3) satırı bulunuyor ve bu satırı çalıştırmaya başlıyoruz. Bir önceki adımda olduğu gibi ekrana 3 yazılrak bu fonksiyonda bitiyor ve artık yaz(2) ile başlayan fonksiyonu bitirmiş oluyor ve ilk başta geldiğimiz * işaretli yere dönüyoruz.

    * işaretli fonksiyonumuzda ise hala yaz(2) şeklinde çalıştırılmayı bekleyen bir satır daha var bunu da benzer şekilde çalıştırıyoruz ve ekrana bu fonksiyon için de bir kere 2 ve iki kere 3 sayısını basıyoruz.

    Sonuç olarak yukarıdaki kodumuz,
    yaz(1) için
    ekrana 1 bas
    yaz(2) çağır
    yaz(2) çağır

    yaz(2) için
    ekrana 2 bas
    yaz(3) çağır
    yaz(3) çağır

    yaz(3) için
    ekrana 3 bas

    şeklinde incelenebilir. En altta bulunan yaz(3) fonksiyonunu bir üstte bulunan yaz(2) içerisine koyarsak:

    yaz(2) için:
    ekrana 2 bas
    ekrana 3 bas
    ekrana 3 bas

    ve son olarak bu yaz(2) tanımını, bir üstte bulunan yaz(1) içine koyarsak:

    yaz(1) için
    erana 1 bas
    ekrana 2 bas
    ekrana 3 bas
    ekrana 3 bas
    ekrana 2 bas
    ekrana 3 bas
    ekrana 3 bas

    şeklinde sonuç elde edilmiş olunur. Görüldüğü üzere bu fonksiyondan beklenen, ekrana, ” 1 2 3 3 2 3 3 ” basmasıdır.

  6. Ahmet

    Şadi bey size cok tesekkur ederim,ancak bukadar anlatılabilirdiki kodu satır satır acıklamıssınız.özyinelemeli algoritmalara karsı korkumu yendim su anlatımınızdan sonra.Tekrar cok tesekkur ederim verdiğiniz emek dolu anlatımınız için

  7. Şadi Evren ŞEKER Article Author

    Rica ederim. Mesajınızı tekrar okuyunca dikkatimi çekti, 123 sayılarından sonra 4 bastırmak gibi bir probleminiz varsa yukarıdaki yazıda 1’den 10’a kadar sayıları bastıran bir kod bulunuyor. Ancak yine de olayın daha iyi anlaşılabilmesi için şu yazılara bakmanızda fayda olabilir:

    http://www.bilgisayarkavramlari.com/2008/08/13/devamsal-gecis-tarzi-continuation-passing-style-cps/

    http://www.bilgisayarkavramlari.com/2008/08/12/kuyruk-ozyinelemesi-tail-recursion-birikimsel-tarz-accumulation-style/

    Bu iki tarz arasındaki farkı kavramanız, özyineli fonksiyonları daha iyi anlamanızı sağlar.

  8. Gokce AYDIN

    Hocam birden fazla class işin içine girince karısıyor.önce nereyi yazalım böyle durumda ? main’i mi? Yani yukarıdaki recursive de control main() başlıyor ancak main() i en son yazıyoruz? bir tavsiyeniz var mı ?

  9. Gokce AYDIN

    Ve hocam bir şey daha soracağım.Şimdi biz önce bir ve sıfırı kontrol edip 1 döndürüyoruz.Recursive de 0 ve 1 için ayrı mı düşüneceğiz? Onun neden fonksiyonda kontrol edilmediğini tam anlayamadım.

  10. Şadi Evren ŞEKER Article Author

    Özyineli fonksiyonlarda (recursive) bitiş koşulu için serinin ilerlemesi takip edilmelidir. Örneğin fibonacci serisi için iki farklı başlangıç değeri vardır ve F(0) = 1 ve F(1) = 1 şeklinde ikisinin de ayrı ayrı düşünülmesi gerekir.
    Seriniz örneğin faktöriyel hesaplamak için kullandığınız ardışık sayılardan oluşuyorsa, bu durumda F(0) = 1 kontrolü yeterlidir çünkü F(1) = F(0) * 1 olarak hesaplanacak ve F(1) değeri de 1 olarak bulunacaktır. Kısacası özyineli fonksiyonlar için serinin açılımına bakmanız ve nerede bitmesini istediğinizi belirlemeniz gerekir.

    Bir önceki yorumunuzda birden fazla sınıf’tan (class) bahsetmişsiniz. Bu sorunun özyineli fonksiyonlarla bir ilgisi yoktur. Sınıf tanımlarının içerisinde bulunan fonksiyonların özyineli olması durumunda fonksiyonu, sınıftan bağımsız düşünerek kodlamanız mümkündür.

    başarılar

  11. Gokce AYDIN
    int sayi,us,toplam,sonuc;
    
    int fak(int a)
    {
    	
    	if(a==1||a==0)
    	{
    		return 1;
    	}
    	else
    	{
    		return a*fak(a-1);
    	}
    
    
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	
    	cout< <"bir sayi giriniz:"<>sayi;
    	int sonuc = fak(sayi);
    	cout< <"Sonuc:"<
    

    Hocam şimdi şu kodda yorum yapmak istiyorum.İnanın burada eksiğim var okulda hocaya soramıyorum.Şimdi burada sayiyi giriyoruz.daha sonra fak fonksiyonuna sayimiz giriyor ve sonuc olarak atanıyor.İşte benim burdan sonra anlayamadığım şu : SORU 1: bu satırdan sonra işlem yukarıdaki fak fonksiyonuna mı gidiyor ?
    SORU 2 :Ve fak()'in main() fonksiyonun altında tanımlanması fark eder mi ?
    SORU 3:Eğer girilen sayi 0 veya 1 değilse de RETURN ediliyor.RETURN nereye edilir ve manası 0 veya 1 değilse 0 ve 1 i mi bas demek?
    SORU 4: Bu return Maindeki fak() fonksiyonuna a*fak(a-1) 'i bir parametresi olarak mı gönderiyor yani Main()de fak(a*fak(a-1) şeklinde ?
    Hocam inanın kafam karıştı.İnanın benim gibi burda çok takılan vardır yeni başlayan.Şimdiden teşekkürler hocam

  12. safa
    #include 
    #include 
    int fak (int a);
    int main(){
        int i,c;
        printf("sayigir");
        scanf("%d",&i);
        c=fak(i);
        printf ("%d",c) ;
        getch();
        return 0;
    }
    int fak(int a){
        
        if(a==1)return 0;
        else   
        return a* fak(a-1);
    
    }
    

    hocam sonucu hep 0 veriyor. hata nerde acaba

  13. Şadi Evren ŞEKER Article Author

    🙂 faktoriyel alırken sayılar çarpılır. Çarpma işleminde 0 yutan elemandır yani bir kere 0 ile çarptığınızda sonuç sıfır olur. kodunuzdaki return 0 bu anlamda hatalı. return 1 olarak düzeltirseniz çalışır. if(a==1) return 1; olacak.

    başarılar

  14. tolga

    Dörtlü arama algoritması (ikili arama algoritmasına benzer şekilde) sıralı bir dizideki elemanları 4’e bölerek arama mantığında çalışmaktadır. Bu arama algoritmasının tekrarlamalı yapı (recursive function) kullanarak programlayınız?

    hocamız boyle bir odev verdi.bir mantık yurutemedik.yardımcı olursanız cok memnun olurum.

  15. Şadi Evren ŞEKER Article Author

    Sanırım hocanız quad tree olarak bilinen ağacı kast etmiş. Genelde 2 boyutlu veriler için daha kullanışlıdır ve veriyi kuzeybatı, kuzeydoğu, güneydoğu, güneybatı şeklinde 4’e böler (bir kareyi ortasında bir artı varmış gibi 4’e böldüğünüzü düşünün). Sanırım internette quadtree olarak aratırsanız işinize yarar bilgiler bulabilirsiniz.

    başarılar

  16. Hasret Dicle

    merhaba,
    Ben “This is a simple string.” cümlesini “Thisisasimplestring.” seklinde
    hem iterative hemde recursive olarak yazmak istiyorum.ityerative yazdim ama
    recursive yapamadim.Nasil yapabilirim?asagidaki iterative hali.

    #include 
    #include 
    
    #define SIZE 30
    
    void blank_search(char *string);
    void blank_search2(char *string);
    
    int main()
    {
        char string[]="This is a sample string.";
        
    //  blank_search(string);
        printf("***********************n");
        blank_search2(string);
        return 0;
    }
    
    void blank_search(char *string)
    {
        int j=0;
        char temp[SIZE],
             temp2[SIZE],
             temp3[SIZE];
    
        while(string[j] != ''){
            if(string[j] == ' '){
                strncpy(temp,string,j);
                temp[j]='';
                strcpy(temp2,&string[j+1]);
                strcpy(temp3,temp);
                strcat(temp3,temp2);
                printf("%sn",temp3);
                strcpy(string,temp3);
            }        
            j++;
       }
    }
    
  17. Şadi Evren ŞEKER Article Author

    üçgen olabilmesi için iki kenarın uzunluklarının toplamının 3. kenardan büyük olması gerekir.

    Yani 1,1,3 kenarlarına sahip bir üçgen olamaz çünkü ilk iki kenarın uzunlukları toplamı ( 1 + 1 = 2 ) üçüncü kenardan kısadır.

    Bu durumda kod aşağıdaki şekilde yazılabilir:

    int ucgenmi (int a,int b, int c){
       if(a + b > c && a+c > b && c+b > a)
          return 1;
       return 0;
    }
    
  18. Anonim

    Merhaba,
    Bir dizin içerisindeki dosyaları ve alt dizinleri özyüneli olarak dolaşan fonksiyonu nasıl yazabiliriz acaba?
    Teşekkürler.

  19. Şadi Evren ŞEKER Article Author

    Sanırım mail de atmışsınız, kodunuzu inceledim, anladığım kadarıyla C dilinde yazmaya çalışıyorsunuz, bu durumda bir problem dizin ve dosya bilgilerinin okunduğu fonksiyonların işletim sistemi bağımlı olmasıdır. Aşağıda verilen listdir fonksiyonu sanırım işinizi çözer. Ben MacOSX’de denedim sorunsuz çalışıyor sanırım linux / unix türevi makinelerde de çalışır.

    #include 
    #include 
    #include 
    #include 
    #include 
    
    void listdir(const char *name, int level)
    {
        DIR *dir;
        struct dirent *entry;
    
        if (!(dir = opendir(name)))
            return;
        if (!(entry = readdir(dir)))
            return;
    
        do {
            if (entry->d_type == DT_DIR) {
                char path[1024];
                int len = snprintf(path, sizeof(path)-1, "%s/%s", name, entry->d_name);
                path[len] = 0;
                if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                    continue;
                printf("%*s[%s]n", level*2, "", entry->d_name);
                listdir(path, level + 1);
            }
            else
                printf("%*s- %sn", level*2, "", entry->d_name);
        } while (entry = readdir(dir));
        closedir(dir);
    }
    
    int main(void)
    {
        listdir(".", 0);
        return 0;
    }
    

    Şayet farklı bir ortama geçerseniz include edilen dosyaları ve kullanılan yapıları (struct) değiştirmeniz gerekir, ortam hakkında bilgi vermemişsiniz ama linux ortamındaysanız sorun çıkmaz.

    Recursive (özyineli) fonksiyon yazılırken, dikkat edilecek bir iki husus “.” özel dizindir ve current directory (içinde bulunulan dizin) anlamındadır özel olarak if ile engellemezseniz aynı dizinde takılır kalırsınız, benzer şekilde “..” üst dizin demektir ve dikkat edilmesi gerekir.

    Başarılar

  20. öğrenci

    hocam yıldız şeklinin uçlarında sehirler var ve yıldızın içinde altıgenin köşelerinde şehirler var bu şehirler arasındaki bütün yolları bulan programı yazmam gerekiyo nasıl bi algoritma kullanabilirim ?

  21. oğuz

    Asagida verilen islemleri Menu olarak listeleyen ve uygun verilerle cagirp calistiran bir program yaziniz.
    1. Verilen n sayisina kadar olan sayilari recursif (kendi kendini cagiran fonksiyon) olarak toplayan bir fonksiyon yaziniz.
    2. Klavye den girilen 2 rasyonel sayinin (a/b) ve (c/d) toplayarak sonucu (d/e) seklinde gosteren bir fonksiyon yaziniz.
    3. Klavyeden girilen [-50…50] araliginda sayilari degerlendiren ve herhangi 2 sini carpiminin 20 olmasi halinde “Evet” ve diger carpimlar icin “Hayir” yazan bir fonksiyon yaziniz.
    4. Verilen 1 paragraf yazinin icerisinde kac cumle, kac kelime ve her harfin kac defa yer aldigini gosteren bir fonksiyon yaziniz.
    5. Verilen 10 elemanli ondalik sayi dizisinin en buyugunu, en kucugunu ve en cok tekrar eden sayiyi bulan bir fonksiyon yaziniz.

    yardım ederseniz sevinirim.

  22. id

    Hocam örneğin m tabanında 2 sayımız olsun bu 2 sayıyı 10 tabanına çevirmeden m tabanında toplamamız gerekiyor.Programın recursive olması gerekiyor.bunu nasıl yapabiliriz acaba?

  23. Şadi Evren ŞEKER

    Oğuz beyin konu ile ilgili (recursive) sorusunu cevaplamaya çalışayım. Soru: “Verilen n sayisina kadar olan sayilari recursif (kendi kendini cagiran fonksiyon) olarak toplayan bir fonksiyon yaziniz.”

    int topla(int n){
       if(n==1)
         return 1;
       return n+topla(n-1);
    }
    

    Diğer sorularınızı lütfen ilgili konuların altında sorunuz.

  24. Şadi Evren ŞEKER

    id isimli kullanıcının sorusunu cevaplayalım, soru şu şekilde: ” m tabanında 2 sayımız olsun bu 2 sayıyı 10 tabanına çevirmeden m tabanında toplamamız gerekiyor.Programın recursive olması gerekiyor.bunu nasıl yapabiliriz acaba?”

    Öncelikle herhangi bir tabandaki toplama işlemini hatırlayalım. Örneğin 4 tabanında verilmiş aşağıdaki sayıları ele alalım:

    123
    122

    bu sayıları toplarken izleyeceğimiz yol şu şekilde:

    birler basamağında 3+2 = 5, bu sayının mod 4 değeri, 5%4 = 1 dolayısıyla toplamın birler basamağı da 1 olacak ancak elde var 1.

    dörtler basamağında 2 + 2 + 1 (elde vardan gelen) = 5 ve yine 5%4 = 1 ve yine elde var

    onaltılar basamağında 1 + 1 + 1 (elde vardan gelen) = 3

    sonuç 311 olarak bulunur.

    şimdi bu hatırlatmaya bakacak olursak sayılar her seferinde birler basamağından işlenecek, sayıların basamağı küçültülecek ve toplamın basamak değeri arttırılacak. Yani, yine örneğimizi düşünürsek 123 olan sayının ve 122 olan sayının son basamakları (birler basamağı) toplandıktan sonra sayıların basamakları küçültülüp son basamakları atılacak ve 12 ve 12 haline getirilecek. Toplamda ise 11 elde edilecek. Sondaki 1 toplamın sonucu diğer 1 ise elde var değeri. Ardından 2 ile 2 toplanacak ve toplam sonucun 4’ler basamağına yazılacak (aslında integer olduğu için 10lar basamağı) böylece işlem devam edecek.

    Kodu kabaca aşağıdaki şekilde yazılabilir:

    #include 
    int topla(int a,int b, int basamak){
       if(a==0)
         return b;
       if(b==0)
         return a;
       return (a%10+b%10)>=basamak?10+(a%10+b%10)%basamak+10*topla(a/10,b/10,basamak):(a%10+b%10)%basamak+10*topla(a/10,b/10,basamak);
    }
    int main(){
      int a=123;
      int b=122;
      printf("%d",topla(a,b,4));
    }
    
  25. ahmet

    merhaba hocam , java ile matrislerin çarpımı ve matrislerin toplamı için recursif özyinelemeli bir metod yazabilirmisiniz . cok ugrastım yapamadım yardımcı olursanız sevinirim.

  26. ahmet

    Merhaba Hocam;
    recursif(özyinelemeli) halini rica etsem yazabilirmisiniz Lütfen yardımcı olurmusunuz.. Dikkate alırsanız sevinirim…

     public static int[][] multiply(int[][] a, int[][] b) {
           int rowsInA = a.length;
           int columnsInA = a[0].length; // same as rows in B
           int columnsInB = b[0].length;
           int[][] c = new int[rowsInA][columnsInB];
           for (int i = 0; i < rowsInA; i++) {
               for (int j = 0; j < columnsInB; j++) {
                   for (int k = 0; k < columnsInA; k++) {
                       c[i][j] = c[i][j] + a[i][k] * b[k][j];
                   }
               }
           }
           return c;
       }
    }
    
  27. mustafa

    sa hocam bi sorum olucakti eger yardimci olabilirseniz.Bi programy azmak istiyorum ama nasil olacagini bilmioyrum

    abcdef ve axczyfab —-> 0,3,5 uzunluk 3 ..
    cvp böyle olucak hocam verilen ifadeleri karsilastiriyor ve ayni siradakileri rakamla yaziyor..mesela ilk basta 0 ilk srada digeirnde de var ve ilk sirada 0 yaziyor…sonra c ler ayni oldugu icin c yi yazdiriyor..sonrada f yi yazdiriyor.sirasina göre ve en sonda kac tane ayniysa onu yazidriyor..yardimci olabilirmisiniz

  28. Elif

    Merhaba hocam, yardım ederseniz çok sevinirim.
    Aşağıdaki metod ne işe yarar? Bu metodu özyinelemeli(recursive) olarak tekrar yazınız.
    Not: Recursive yazacağınız yeni metot için metot imzasını (alacağı parameterleri) değiştirmeniz gerekebilir.
    static bool MetotX(int [] array, int anahtar)
    { int i = 0, n = array.GetLength(0);
    for (i = 0; i < n; i++)
    { if (array[i] == anahtar)
    { return true; }
    }
    return false;
    }

Şadi Evren ŞEKER için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir