[Çözüldü] Bir Cümlede ki en büyük kelimeyi basan program.

Başlatan Ozgurluk, 27 Kasım 2011 - 16:04:13

« önceki - sonraki »

0 Üyeler ve 4 Ziyaretçi konuyu incelemekte.

Ozgurluk

Böyle bir program yazmaya uğraşıyorum C'de çok denemeler yaptım. Algoritmasını oluşturamadığım için kodlamada çok zaman kaybettim. Yazdığım kod çalışmadı malesef. :( Böyle bir program nasıl bir algoritma ve hangi fonksiyonları kullanarak kodlanabilir.

Saygılarımla...

alquirel

En büyük kelime derken?

Harf sayısı bakımından en uzun kelime ise eğer, önce cümleyi kelimelere bölersiniz. daha sonra bir döngü ile en uzun kelimeyi bulursunuz. Döngü sonlandığında da en uzun bulunmuş olan kelimeyi yazdırırsınız.

Ozgurluk

#include <stdio.h>
int main(){
    char cumle[100]; //100 karakterlik cümle almak için.
    char *k_bas; //kelime başının adresini tutmasi için.
    char *k_sonu; //kelime sonun adresini tutmasi için.
    int i,enb,y_boy; //en büyük boy (enb); yeni boy(y_boy);
   
    enb=0; y_boy=0;
    k_bas = &cumle[0];
    printf("En uzun kelime bulunacak cumleyi giriniz.");
    gets(cumle);
    for(i=0;i<=strlen(cumle);i=i+1){
        y_boy=y_boy+1;                         
        if (cumle [i] =' '){//Döngüde harf boşluk karakterine geldiği zaman
           if(y_boy>enb){//y_boy>enb; enb=y_boy olarak ata
           enb=y_boy;
           k_bas = k_sonu;
           }
        }
    y_boy=0; 
    }   
    printf("Cumledeki en uzun kelime =%s",k_bas);
    sleep(1000);
    getch();
}


Aslında, programlarken basit olarak planım şuydu yazıyım. iki tane pointer değişken tanımlayıp, kelimenin başını ve kelimenin sonunun hangi indis olduğunu tutacak. Daha sonra sayaç içersinde kelimenin uzunluğunu sayacak. Eğer cümlede ki en uzun kelime oysa onun pointer'in tuttuğu adres değerleri basacak. Fakat çıkamıyorum işin içinden yardım.

Şimdiden Teşşekkürler!


Mesaj tekrarı yüzünden mesajınız birleştirildi. Bu mesajın gönderim tarihi : 27 Kasım 2011 - 16:12:30

Alıntı yapılan: alquirel - 27 Kasım 2011 - 16:09:03
En büyük kelime derken?

Harf sayısı bakımından en uzun kelime ise eğer, önce cümleyi kelimelere bölersiniz. daha sonra bir döngü ile en uzun kelimeyi bulursunuz. Döngü sonlandığında da en uzun bulunmuş olan kelimeyi yazdırırsınız.

Bende öyle plandım @alquirel'da çıkamadım işin içinden programlama bilgimde az.

alquirel

Önce algoritmanız üzerinden cevaplayayım. Daha sonra algoritmayı geliştiririz.

y_boy değişkenini yanlış yerde sıfırlıyorsunuz. Yani döngü her döndüğünde y_boy sıfırlanıyor.
Böyle olunca da y_boy ile enb'nin karşılaştırmasını yapmak anlamsız oluyor.

y_boy değişkeninin sıfırlanması işini if(y_boy>enb) karşılaştırmasını yaptığınız blok içerisinde yapın.

Ozgurluk

Teşşekkürler, Fakat gene bir hata var benim kode'da içerde de y_boy değişkenini sıfırlayınca gene kod enb değişkeni, en büyük kelimenin harf sayısını üretemiyor.
#include <stdio.h>
int main(){
    char cumle[100]; //100 karakterlik cümle almak için.
    char *k_bas; //kelime başının adresini tutmasi için.
    char *k_sonu; //kelime sonun adresini tutmasi için.
    int i,enb,y_boy; //en büyük boy (enb); yeni boy(y_boy);
   
    enb=0; y_boy=0;
    k_bas = &cumle[0];
    printf("En uzun kelime bulunacak cumleyi giriniz.");
    gets(cumle);
    for(i=0;i<=strlen(cumle);i=i+1){
        y_boy=y_boy+1;                         
        if (cumle [i] =' '){//Döngüde harf boşluk karakterine geldiği zaman
           if(y_boy>enb){//y_boy>enb; enb=y_boy olarak ata
           enb=y_boy;
           y_boy=0;
           }
        }
    }   
    printf("Cumledeki en uzun kelimenin harf sayisi=%d",enb);
    sleep(1000);
    getch();
}

alquirel

Kodunuzda düzeltilecek yerler var.

* strlen fonksiyonu için string.h kütüphanesini eklemeniz lazım. Gözden kaçmış olmalı
* if(cumle[ i] = ' ') karşılaştırmasında iki eşittir kullanmanız lazım.
* y_boy değişkenini arttırmayı boşluk karakteri kontrolünü yaptığınız if'ten sonra yapın. Aksi durumda boşluk karakteri de en uzun kelimenin harf sayısına eklenmiş oluyor.

Ozgurluk


#include <stdio.h>
#include <string.h>
int main(){
    char cumle[100]; //100 karakterlik cümle almak için.
    char *k_bas; //kelime başının adresini tutmasi için.
    char *k_sonu; //kelime sonun adresini tutmasi için.
    int i,enb,y_boy; //en büyük boy (enb); yeni boy(y_boy);
   
    enb=0; y_boy=0;
    k_bas = &cumle[0];
    printf("En uzun kelime bulunacak cumleyi giriniz.");
    gets(cumle);
    for(i=0;i<=strlen(cumle);i=i+1){
        if (cumle [i] ==' '){//Döngüde harf boşluk karakterine geldiği zaman
        y_boy=y_boy+1;
           if(y_boy>enb){//y_boy>enb; enb=y_boy olarak ata
           enb=y_boy;
           y_boy=0;
           }
        }
    }   
    printf("Cumledeki en uzun kelimenin harf sayisi=%d",enb);
    sleep(1000);
    getch();
}


Dediğiniz gibi kodu düzenledim fakat gene 1 üretiyor. En uzun kelimenin harf sayısı olarak.

alquirel

Beni yanlış anlamışsınız. y_boy değişkenini arttıracağınız yer if'in içi değil, sonrası olmalı.
Yani


        if (cumle [i] ==' '){//Döngüde harf boşluk karakterine geldiği zaman
           if(y_boy>enb){//y_boy>enb; enb=y_boy olarak ata
             enb=y_boy;
             y_boy=0;
           }
        }
        else y_boy=y_boy+1;



Ozgurluk

Gene hatalı sonuçlar üretiyor, enb değer olarak ilk girilen kelimenin harf sayısını ekrana basıyor.

alquirel


#include <stdio.h>
#include <string.h>
int main(){
    char cumle[100]; //100 karakterlik cümle almak için.
    int i,enb,y_boy; //en büyük boy (enb); yeni boy(y_boy);
   
    enb=0; y_boy=0;
    printf("En uzun kelime bulunacak cumleyi giriniz.\n");
    gets(cumle);
    for(i=0;i<=strlen(cumle);i=i+1){
        if(y_boy>enb) //y_boy>enb; enb=y_boy olarak ata
              enb=y_boy;

        y_boy=y_boy+1; //y_boy değişkenini arttır.

        if (cumle [i] ==' ') // boşluğa geldiysek sıfırla.
           y_boy=0;
    }   
    printf("Cumledeki en uzun kelimenin harf sayisi=%d\n",enb);
}


Düzenlemelerim :

* enb değişkenini y_boy daha büyük olduğu sürece başka şarta kalmadan güncellemek.
cümle sonu enter tuşuyla girildiğinden son kelimeyi de denetleyebilmek adına yaptım bunu

* k_bas ve k_son değişkenlerini gereksiz olduğu için sildim.

* Bu haliyle bende sorunsuz çalışıyor.

Ozgurluk

#10
@alquirel Teşşekkürler!

if

@Ozgurluk ve @alquirel'in son mesajlarına binaen sorunun çözüldüğü yorumunu yapıp konuyu kilitliyorum.

alquirel

Başlığa konu olan problemin tam çözümünü henüz yapmadığımız için @if'in müsaadesiyle etiketi kaldırıyorum.

@Ozgurluk, harf sayısını değil de kelimeyi yazan kod çalışmalarını paylaşmanı bekliyoruz ;)
İpucu olarak bir anlatım gönderiyorum : http://www.cplusplus.com/reference/clibrary/cstring/strtok/

sem

Ödev ne ödevidir bilmiyorum... Fakat göstericileri işlediyseniz eğer doğruluğunu test etmediğim şu kodu ve açıklamalarını daha sonraki arkadaşlara da örnek kod olması açısından paylaşılıyorum... Doğruluğunu test etmediğim için sadece fikir vermesi açısından paylaşıyorum...



#include <stdio.h>
#include <string.h>

int main()
{
char cumle[101];
int len = 0;
fprintf(stdout, "Cümleyi girin:");
fgets(cumle, 100, stdin);

//enter (\n) karakterini ayıkla, son kelimeyi de bulabilmek için boşluk olarak değiştir.
len = strlen(cumle);
cumle[len -1] = ' ';

char *begin = cumle;  //aramaya en baştan başlayacağız.
char *end = NULL;     //bulduğumuz kelimenin bitişi, bir sonraki kelimemizin başlangıcını bulmakta kullanılacak

char *tmp_begin = NULL;
int tmp_len = 0;

while((end = strstr(begin, " ")) != NULL)  // boşluk karakteri bulunmayana kadar döngüye devam
{
--end; //strstr fonksiyonu end fonksiyonunu boşluğa konumlandırdır. Bu konumu boşluktan önceki karaktere çekiyoruz
int cur_len = end - begin; // kelimemizin uzunluğu
if(cur_len > tmp_len ) // güncel uzunluk, bir önceki uzunluktan büyükse ilgili birimlerde değişiklik yapıyoruz
{
tmp_begin = begin; // en uzun kelimenin başlangıç adresi
tmp_len = cur_len; // en uzun kelimenin uzunluğu
}
begin = end+2;  // bir önceki kelimeden bir sonraki karakter boşluk oluyor. O nedenle biz boşluktan da bir sonraya konumlandırıyoruz. O nedenle +2 yaptık
}

//kelimeyi yazdır
int i;
++tmp_len;
for(i = 0; i < tmp_len; ++i)
fprintf(stdout, "%c", tmp_begin[i]);


return 0;
}



Bunun dışında size bir kaç öneri vereceğim yanlış anlamazsanız eğer;


for(i=0;i<=strlen(cumle);i=i+1)

gibi bir ifade kullanmışsınız. Bilemiyorum derleyici cumle değişkeninin  değişmediğini görünce optimizasyon konusunda bu konuya el atar mı fakat bu gibi şeyler nasıl alışılırsa öyle gidiyor, o nedenle belirtmek istedim; burada dögünün her aşamasında strlen fonksiyonunu çağırıyorsunuz... İleride çok daha büyük döngüler ile işlem yapabilirsiniz. O nedenle döngüler içerisinde olabildiğince fonksiyon çağırmalarında kaçınmanızı öneririm;

int tmp_len = strlen(cumle);
for(i=0;i<=tmp_len;i=i+1)


ifadesi ile strlen'i döngü içerisinde çağırmaktan kurtulabilirsiniz. Bu size işlemci süresi olarak geri dönecektir.

Bir başka konu ise, yine ileriye yönelik söyleyeyim çünkü bu programın çökmesi kritik bir hata oluşturmayabilir ama çökme durumlarını kulanıcı hatalarından ayırmak için gets fonksiyonunu kullanmamızı öneririm...

GCC zaten uyarı verir gets kullanında ama siz Windows ortamında çalışıyorsunuz sanırım. gets fonksiyonu kullanıcının girdiği karakter sayısını denetlemez. O nedenle 10 karakter uzunluğunda istediğiniz  bir girdiyi kullanıcı 50 karakter olarak girerse ve siz bunu gets ile alıyor olursanız programınızda "Segmantation fault" göreceksiniz =) O nedenle fgets kullanmanızı öneririm. fgets dosyadan okuma işlemleri için kullanılır fakat stdin dosyasına yönlendirip klavyede giriş alabilirsiniz. Gönderdiğim kod parçasında örneği mevcut. Bu şekilde kullanıcı 10000 karakter girse de istediğiniz kadarını işleme sokma ihtimaliniz olur.

Okunabilirlik açısından da ++ ya da += operatorlerini incelemenizi tavsiye ederim...

Kolay gelsin...
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?

Ozgurluk

Sem çok teşşekkür ederim. Bunlar faydalı oldu, benim için konuyu çözüldü olarak işaretliyebiliriz...@alquirel ve sem'e Teşşekkürlerimle.

alquirel

@Ozgurluk,

Çözüldü etiketlerini siz de koyabilirsiniz ilk iletinizi düzenleyerek.
Kilitliyorum.