c yardim??

ermess
10-02-2011, 22:55   |  #1  
OP Üye
Teşekkür Sayısı: 0
57 mesaj
Kayıt Tarihi:Kayıt: Kas 2010

(12+5(-3(134-19)-)9+5)   bunun gibi kullanicinin girdigi  matemaikisel işlemleri işlem önceligine ve parentezleri dogru şekilde düzeyenleyen  ve cıktı ve c prog.nasil olur??? yardimci olursaniz sevinirim

muh34
12-02-2011, 02:19   |  #2  
Yıllanmış Üye
Teşekkür Sayısı: 0
215 mesaj
Kayıt Tarihi:Kayıt: Eki 2010

Sormus oldugunuz soru klasik bir hesap makinası programının C dilinde kodlanmasıdır.Soru bilgisayar ve yazılım mühendisliği bölümlerinde proje niteliği tasıyan bir uygulamadır.Ancak kurgulanacak algoritma problemin cozumu adına sizin için yeterli olacagının kanatindeyim.
Bilindiği üzere matematikte 4 işlem yontemi icerisinde onceliği olan operatorler çarpım(*) ve bolum(/) operatorleridir.Şayet bu operatorler birer parantez  ' () ' operatoru içerisinde kullanıldıgında ilgili parantez işlemi içerisindeki uygulama öncelik kazanır.Dolayısıyla parantez operatorleri arasında kalan işlemler herzaman önce uygulanmaktadır.Bu yuzden tasarlanacak algoritma icerisinde parantezler kilit noktalar olusturmaktadır.C dili içerisinde kullanıcı işlem bileşenlerini manuel veya dolaylı olarak kendisi girdiği için kullanılacak ilk yapı karakter katarı(String) olacaktır.

char islemler[]={ " (2*(3+5))-3 "}; şeklinde bir yapı veyahut da bir input fonksiyonu ile katarın içerisine işlem bileşenlerini girebilir.
Kullanıcı cozulmesini istedigi işlemi bilgisayara verdikten sonra gerekli dogru sonuc için algoritmayı kurgulayabiliriz.
Daha oncesinde parantezlerin kilit noktalar oldugunu dile getirmiştik.O halde ikinci bir dizi yaratarak bu parantezlerin ilgili String icerisindeki indeks numaralarını tarayarak saklayabiliriz.Bunun için kullanılacak ifadeler,

int parantezDizisi[5];
int k=0; // parantezDizisi icin kullanılan sayaç
int diziBoyu=length(islemler);
for(i=0;i<diziBoyu;i++)
if(islemler=='(')
parantezDizisi[k++]=i;
yazılabilir.

Artık açık parantez noktalarını bildiğimize gore bu parantez noktalarına teker teker erişerek temel aritmetik işlem algoritmasını uygulayabiliriz.Temel aritmetik işlem algoritmasında iki adet sayısal deger ve bir adette operator bulunmalıdır.Ancak,standart C programlama dili icerisinde string veri tipi char[] karakter dizisi olarak kullanıldıgı icin biraz daha fazla işlem yapmamız gerekecektir.Çünkü karakterler tek tek taranırken kullanıcının girdiği sayısal degerin kac basamaklı oldugu bilinmemektedir.Dolayısıyla bunun için bir alt algoritma(subAlgorithm) daha kurgulamamız gerekecektir.
Yapmamız gereken,tarama uygulamasında operator gorene kadar islemlerDizisinden alınan karakterler bir baska gecici karakter dizisininde biriktirilecektir.Şayet tarayıcı herhangi bir operator ile karsılasırsa ilk tarama sonlanacak ve daha onceden cekilen alt karakterler bir converter fonksiyonu kullanılarak sayısal bir veri turune donusturulecektir.Ornegin char * to double donusumu yapabiliriz.Bu işlemi C dili içerisinde double atof(const char *) fonksiyonu gerçekleştirmektedir.
Yukarıda anlatılan alt algoritmayı uygularsak,

char birinciSayi[4]; char ikinciSayi[4]; char operator;
double sonuc=0.0,sayi=0.0; char karakter='*';
int islenenKarakterSayisi=0; // bu degisken daha sonra aciklanacaktır.

int a=k-1; //    ' ( ' taramada kullanılacak son parantezin yerini alan a sayaci
for(i=k-1;i>=0;i--)
{
while(karakter=='+' || karakter=='-' || karakter=='*' || karakter=='/')
{
karakter=islemler;
strcat(birinciSayi,islemler[a++]); // C dilinde iki karakter katarını birleştirmeye yarayan strcat() fonksiyonu.
islenenKarakterSayisi++;
}
sonuc=atof(birinciSayi); // ilk sayı double veri tipli sayısal degere donusturuldu.
operator=karakter; // operator simdi elde edildi
while( karakter!=')' )  // simdi ikinci sayı için tarama,bu sefer kapanis parantezi gorulene dek döngü devam
{
karakter=islemler;
strcat(ikinciSayi,islemler[a++]);
islenenKarakterSayisi++;
}
sayi=atof(ikinciSayi);
if(operator=='+')
sonuc+=sayi;
if(operator=='-')
sonuc-=sayi;
if(operator=='/' && sayi!=0)
sonuc/=sayi;
if(operator=='*')
sonuc*=sayi;

şeklindeki kod satırlarını yazabiliriz.Buraya kadar yapılan işi ozetlemek gerekirse,
1 -> string icerisindeki ' ( ' parantezlerin indeksleri belirlendi
2 -> bu indekslere erisilerek temel aritmetik işlem algoritması uygulandı
3 -> bu sayede karakterler sayısal forma sokularak hesaplar işletildi.

Sorunun buyuk bir kısmı aslında tamamlanmıs gibi gozukmektedir.Ancak yukarıda dikkat edilirse
for(i=k-1;i>=0;i--) dongusu gorulmektedir.Bu dongu String icerisindeki acık parantez sayısı kadar işlemektedir.Yani parantez adedi kadar işlem onceliğini ayarlamaktadır.Dolayısıyla yukarıdaki yapmıs oldugumuz işlemler parantez sayısı kadar işlemesi gerekir.(Ki for dongusu bu yuzden tanımlanmıstır).
Peki en icteki parantez icerisindeki işlemi gercekleştirdigimize gore,diger parantez icerisindeki işlemler için nasıl bir yontem izleyebiliriz ? Algoritmanın düşünülmesi zor olan kısımlarından biri burasıdır.Bunun için çeşitli metotlar one surulebilir.Kişisel dusuncem su ki,dizi icerisindeki parantez noktalarını bildigimize gore(parantezDizisi[]),işlem yaptıgımız her parantezi,kullanıcının girmiş oldugu işlemler stringinden kaldırırsak dıştaki parantezlerin cozumu için aynı mantıgı rahatlıkla kullanabiliriz.O halde daha once yazılan if() koşul operatorlerinin altına string delete işlemini uyarlayabiliriz.Bunun için en içteki açık parantez noktasına kadar dizinin sonundan kaydırma işlemi yapılabilir.Bu ise daha onceden tanımlanmıs islenenKarakterSayisi degiskeni yardımıyla yapılacaktır.Cunku diziden islenenKarakterSayisi kadar kaydırma işlemi gercekleşir.

for(e=0;e<islenenKarakterSayisi;e++,diziBoyu--)
for(d=parantezDizisi;d<diziBoyu;d++)
islemler[d]=islemler[d+1];

islenenKarakterSayisi=0;
} // for(i=k-1;i>=0;i--) dongusu sonu

Sonuc olarak elde edilen sonuc degeri ekranda bastırılarak problem cozulmus olacaktır.
printf("Islem Sonucu:%lf",sonuc);
} // program sonu

Sorunuzun algoritması dısında neredeyse programın tamamını parca parca yayımlamış bulunmaktayım.Bazı noktalarda sayfanın karısıklıgı nedeniyle küçük hatalar olabilir.Ancak problem cozumu için fazlasıyla fikir verdiginin kanatindeyim.

Başarılar

ermess
13-02-2011, 23:03   |  #3  
OP Üye
Teşekkür Sayısı: 0
57 mesaj
Kayıt Tarihi:Kayıt: Kas 2010

cok yardımci oldunuz cook tşkler