Duyuruyu Kapat
Facebook Gözat
Twitter Gözat

stack uygulaması

Konu, 'C / C++' kısmında RaiST tarafından paylaşıldı.

  1. RaiST

    RaiST Daimi Üye

    Kayıt:
    24 Temmuz 2002
    Mesajlar:
    1,932
    Beğenilen Mesajlar:
    0
    Meslek:
    linuxrocker
    Şehir:
    krynn
    Buda basit bir stack uygulaması.
    umarım bir işe yarıyordur..

    stack.h
    PHP:
    struct stack
    {
    float data;
    struct stack *next;
    };

    typedef struct stack STACK;

    STACK Push(STACK myStack,float value);
    float Pop(STACK myStack);
    int isFull();
    int isEmpty(STACK myStack);

    stack.c
    PHP:
    #include <alloc.h>
    #include "stack.h"

    STACK Push(STACK myStack,float value)
    {
    STACK * new;
    STACK temp;
    temp=myStack;
    if (
    myStack==NULL)
    {
        new=(
    STACK*)malloc(sizeof(STACK));
        new->
    next=NULL;
        new->
    data=value;
        
    myStack=new;
    }
    else
    {

    while(
    temp->next!=NULL)
    {
        
    temp=temp->next;
    }
        new=(
    STACK*)malloc(sizeof(STACK));
        new->
    data=value;
        new->
    next=NULL;
        
    temp->next=new;
    }

    return 
    myStack;

    }

    float Pop(STACK myStack)
    {
    STACK prev;
    STACK temp;
    int val=0;

    temp=myStack;
    while(
    temp->next!=NULL temp->next!=temp)
    {
        
    prev=temp;
        
    temp=temp->next;
    }


    val=temp->data;


    prev->next=NULL;
    free(temp);



    return 
    val;
    }

    int isFull()
    {
    STACK * new;
    if ((new=(
    STACK*)malloc(sizeof(STACK)))==NULL)
    {
    /* hafiza dolu!! */

        
    return 1;

    }
    else
    {
        return 
    0;
    }


    }

    int isEmpty(STACK myStack)
    {
    if (
    myStack==NULL)
    {
    return 
    1;
    }
    else
    {
    return 
    0;
    }



    }



    test.c
    PHP:
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include "stack.c"


    /* Hseyin Uslu */

    #define DEBUG_STACK 0
    /* DEBUG_STACK=1 yaplrsa program her iŸlemden sonra stackin o anki halini g”sterecektir*/

    void DebugStack(STACK *); /*Stack Debug fonksiyonu */

    void main()
    {

    STACK ourStack=NULL;
    int i;
    float deger;


    clrscr();


    for (
    i=1;i<=10;i++)
    {
        if (
    isFull()==0)
        {
            
    printf("%d. de§eri giriniz:",i);
            
    scanf("%f",&deger);
            
    ourStack=Push(ourStack,deger);
        }
        else
        {
            
    printf("Hazfa dolu! Stack i‡in yeni yer ayrlamyor...");
            
    getch();
            exit(
    0);
        }


    }

    DebugStack(ourStack);
    printf("\n---------- Stack library kullanlarak avarage hesaplanyor... ----------\n");



    while(
    ourStack->next->next!=NULL)
    {
    if (
    isEmpty(ourStack)==0)
    /*stack boŸ de§ilse */
    {
    Push(ourStack,Pop(ourStack)+Pop(ourStack));
    DebugStack(ourStack);
    }
    }

    Push(ourStack,Pop(ourStack)+Pop(ourStack));
    DebugStack(ourStack);

    printf("_____________________________________________\n");
    printf("Avarage=%f",Pop(ourStack)/10);

    getch();

    }

    void DebugStack(STACK myStack/*Stack Debug fonksiyonu */
    /*stacking o anki durumunu ekrana yazdrr */
    {
    STACK temp;

    if (
    DEBUG_STACK==1)
    {
        
    temp=myStack;
        
    printf("[DEBUG - printing current list : ");
        
    printf("%.1f",temp->data);
        while(
    temp->next!=NULL temp->next!=temp)
        {
            
    temp=temp->next;
            
    printf("->%.1f",temp->data);
        }
        
    printf("\n");
    }


    }



     
  2. ee++

    ee++ Daimi Üye

    Kayıt:
    25 Temmuz 2002
    Mesajlar:
    1,122
    Beğenilen Mesajlar:
    0
    Şehir:
    Ankara
    Agir elestiriler: :)

    1- Kod gereksiz olarak uzun.
    2- Kod standart degil.
    3- Kod gelen amacli degil, sadece float degerler için Yığıt yapısı/işlevi sağlıyor.

    Bu üçünü ortadan kaldırırsan güzel olur ve bunu gerçekleştirler var zaten, mesela C++ Standart Kütüphanesi..
    :)
     
  3. RaiST

    RaiST Daimi Üye

    Kayıt:
    24 Temmuz 2002
    Mesajlar:
    1,932
    Beğenilen Mesajlar:
    0
    Meslek:
    linuxrocker
    Şehir:
    krynn
    ağır cevaplar: :):D

    1- hoca /asistanların isteği üzerine yapılabilecek çoğu optimizasyon yapılmaıyor...
    2- standartlara uyma yine yukardaki kişlerin istekleri üzerine yapılamıyor.. yaparsak, yanlış diye işin içinden çıkma durumları yüksek..
    3- genel amaçlı değil yazacaktın galiba.
    evet spesifik bir kod. ödev kağıdında belirtilen şekilde...

    teşekkürler..

    (bu arada bu standartizasyon !yanlış yazdım ehhe! konusunda bir ara görüşelim.. )
     
  4. ee++

    ee++ Daimi Üye

    Kayıt:
    25 Temmuz 2002
    Mesajlar:
    1,122
    Beğenilen Mesajlar:
    0
    Şehir:
    Ankara
    Bu konuda ee++ ve acehreli ile saatlerce süren hamam muhabbetleri yapabilirsin.. :) De mi acehreli? :)
     
  5. RaiST

    RaiST Daimi Üye

    Kayıt:
    24 Temmuz 2002
    Mesajlar:
    1,932
    Beğenilen Mesajlar:
    0
    Meslek:
    linuxrocker
    Şehir:
    krynn
    kısa zaman içinde inşallah:)
     
  6. acehreli

    acehreli Ali Çehreli

    Kayıt:
    19 Ekim 2002
    Mesajlar:
    4,973
    Beğenilen Mesajlar:
    2
    Bu sıralar buraya fazla yazmıyorum ama okuyorum. :eek:)

    Kodun doğru olması konusunda ee++'a katılıyorum. Ancak, nette (veya başka bir yerde, örneğin okulda :) gördüklerini ve duyduklarını her zaman için şüpheyle almak herkesin kendi sorumluluğu. Bu gibi forumlarda görülen kodlarda ne kadar çok yanlış bulunduğunu herhangi birisi bir kaç saatlik okumada anlıyor olmalı :) Tabii öyle olabilmesi için de başkalarının mutlaka yanlışları düzeltmeleri ve daha iyi yöntemler önermeleri gerekiyor. Forumların amacı da bu zaten :)

    Ben de RaiST'in kodu üzerine bir şeyler yazayım:

    - Push, myStack==NULL olduğunda kendisi bir stack oluşturuyor. Ben buna katılmıyorum. Push'u yasal olmayan bir stack'le çağırmak hata kabul edilmeli. Bu durumda ben olsam stack kuran ve bozan iki işlev yazardım. Örneğin

    Kod:
      STACK * ConstructStack();
      void DestructStack(STACK *);
    
    - "isFull gereksiz. Nasıl olsa isEmpty var." Diyecektim ki, isFull'un bellekte yer olup olmadığını anlamaya çalışan bir işlev olduğunu farkettim :) Bu işlevin amacına ulaşması ancak tesadüfen olabilir. isFull 0 döndürse bile ondan sonra yer ayırmaya çalıştığımızda yer bulamayabiliriz. Ya da, isFull 1 döndürdüğünde onu boşverip yer almaya kalksak, yer bulabiliriz. Bunların nedeni, işletim sisteminde belleğin büyüklüğünün, o sırada çalışmakta olan işletim dizileri nedeniyle kıpır kıpır oynuyor olmasıdır. Yani bir an var olan şey, bir an sonra yok olabilir :)

    - İki yerde, mantıksal VE işlemi (&&) yerine bit işlemi VE'nin (&) kullanıldığını gördüm. Örneğin:

    Kod:
    while((temp->next!=NULL) & (temp->next!=temp))
    
    (Okumayı kolaylaştırmak için fazla parantezleri kendim ekledim.)

    Bu bağlamda, bit işleci kullanmanın bir sakıncası yok gibi gözüküyor, çünkü hem sol tarafın hem de sağ tarafın değerleri ya 1 ya da 0 olacak (sanırım).

    Ama sonradan birisi gelip,

    Kod:
    temp->next!=NULL
    
    ifadesinin aslında mantıksal olarak

    Kod:
    temp->next
    
    ifadesine eşedeğer olduğu gerçeğini kullanıp o satırı şöyle değiş4irebilir:

    Kod:
    while(temp->next & (temp->next!=temp))
    
    Şimdi başımız belada. Çünkü her iki taraf da sıfır olmasa da, bit işleci '&' için kullanıldıklarında sonuç sıfır çıkabilir (örneğin, 2 & 1 = 0).

    Ek olarak, mantıksal VE işlecinin kestirme kuralını kullanarak, gerekmedikçe sağ taraftaki ifadeyi işlememe şansı vardır. Yani daha hızlı olabilir.

    Neyse, belki yalnızca küçük bir yanlışlık sonucu yazılmıştı ama bence mantıksal VE işleci (&&) kullanılmalı (iki yerde). Ayrıca, '!=NULL' kısmını kullanmamak da çok yaygın bir kullanım olduğundan, ben şunu yeğliyorum:

    Kod:
    while(temp->next && (temp->next!=temp))
    
    - Push'un içinde şöyle bir arama yapıyoruz: (linear search'ün Türkçe'si nedir?)

    Kod:
    while(temp->next!=NULL)
    {
        temp=temp->next;
    }
    
    Eklenen nesneleri en sona koyacağımıza en başa koysak hem Push daha hızlı olur hem de Pop. Ayrıca stack kavramına da uyuyor. Hep üste koyar ve üstten alırız.


    - isEmpty'ye bakınca sanki şöyle olması gerekiyor gibi geldi.

    Kod:
    int isEmpty(STACK * myStack)
    {
        if (myStack.next==NULL)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    Bunu da daha geleneksel olarak şöyle yazabiliriz:

    Kod:
    int isEmpty(STACK * myStack)
    {
        return myStack.next == NULL;
    }
    
    Yani, sanki değeri NULL olan bir stack yasal olmamalı gibi geliyor. myStack doğru düzgün olmalı da, içindeki birşey NULL olmalı. "Peki o zaman bu durumda data'nın değerinin anlamı ne olacak?" diye düşünürken aslında burada bir düğüm yapısına daha gerek olduğunu düşünmeye başladım. stack yapısında stack'i ilgilendiren genel bilgiler, düğümde de her düğümü ilgilendiren şeyler olmalı:

    Kod:
    struct dugum
    {
        float data;
        struct dugum * next;
    };
    
    struct stack
    {
        unsigned int toplam_oge;
        /* başka şeyler de olabilir */
        /* örneğin istatistiksel bilgiler... */
        /* ... */
    
        struct dugum * top;
    };
    
    Evet, sanırım böyle olunca herşey daha mantıklı...

    - 'void main' standart değildir. Onun yerine standart olan 'int main'i kullanabiliriz.

    - 'avarage' yerine 'average' olacak... Ya da Türkçesi olan 'ortalama'yı kullanabiliriz.

    - Kodun içine açıklamalar koymak iyidir. Ama daha iyisi, açıklamalara gerek bırakmayacak kadar açık kod yazmaktır. Örneğin isEmpty işlevi, hiç açıklamaya gerek bırakmayacak kadar açık. Adından kendisine verilen şeyin (bu durumda stack) boş olup olmadığını bildiren bir işlev olduğu anlaşılıyor. Yani, aşağıdaki açıklama gereksiz:

    Kod:
    if (isEmpty(ourStack)==0)
        /*stack boş değilse */
    
    Hatta, '==0' diyeceğimize '!' işlevini de kullanabiliriz:

    Kod:
    if (!isEmpty(ourStack))
    
    Bazı insanlar o ünlem işaretinin çok zor görüldüğünü düşünerek etrafına boşluklar da koyarlar:

    Kod:
    if ( ! isEmpty(ourStack))
    
    Bunların dışında aslında gerçekten iyi. Anlaşılan ödev olarak da iş görüyor... :)

    Ali