PDA

Tam Sürümünü Görmek İçin : Süper Asal Sayılar


LEthaL
20/04/2003, 00:01
Assağıdaki program kodu sayinin süper asal sayı olup olmadığına bakıyor. Tabi seçilen yöne göre.

Mesela 311; yön olarak da sol seçilmiş olsun

311 -> asal
11 -> asal
1 -> asal

311 soldan süper asal

Mesela 733; yön olarak da sağ seçilmiş olsun

733 -> asal
73 -> asal
7 -> asal

733 sağdan süper asal.

Anlayamadığım nokta açıklama satırı ile belirttiğim yerlerin kaldırılınca programın çalışmaması.

Neden?
Başka bir program kodu var mı aklınıza gelen?

Renkli olsun diye böyle yapıştırdım kodu.

#include <stdio.h>
int basamakbul(int sayi)
{
int basamak=0;
while(sayi!=0)
{
sayi /=10;
++basamak;
}
return basamak;
}
int bolunecek(int sayi)
{
int bolunecek=1;
while(sayi!=0)
{
sayi /= 10;
bolunecek *= 10;
}
return bolunecek;
}
int isPrime(int sayi)
{
int i,dur;
for(i=2; i<=(int)(sayi/2); ++i)
if ( (sayi%i)==0 )
{
dur = 0;
break;
}
else
dur = 1;
return dur;
}
int dropDigit(int sayi, int yon)
{
if ((sayi/10)==0)
return sayi;
else
{
if (yon==1)
sayi /= 10;
else
if (yon==0)
sayi = sayi%(bolunecek(sayi)/10);
}
return sayi;
}
int isSuperprime(int sayi, int yon)
{
int basamak=basamakbul(sayi), dur;
for (;basamak>=0;basamak--)
{
sayi = dropDigit(sayi,yon);
// Ne mantiktir anlamadim gittti alttaki printf satirini kaldirin calismiyor
printf("");
if( ! isPrime(sayi) )
{
dur = 0;
break;
}
}
return dur;
}
void main()
{
static int baslangic, bitis;
int sayi, syc, yon, kactane;
clrscr();
printf("Baslangic degerini girin: ");
scanf("%d",&baslangic);
printf("\nBitis degerini girin: ");
scanf("%d",&bitis);
printf("\nHangi yonden isleme sokulsun (\"1\" sagdan \"0\" soldan): ");
scanf("%d",&yon);
for( syc=baslangic, kactane=0; syc <= bitis; ++syc )
{
if( isPrime(syc) )
{
// Ne mantiktir anlamadim gittti alttaki printf satirini kaldirin calismiyor
printf("");
if( isSuperprime(syc,yon) )
{
++kactane;
printf("%d\n",syc);
}
}
}
printf("\n%d-%d araliginda %d tane super asal sayi var.", baslangic, bitis, kactane);
getch();
}


ee++
20/04/2003, 08:06
Sadece islev isimlerine baktim. Guzel bolmus kim bolduyse. Ama, bilgi girisi icin de bir islev olsa ve clrscr() kullanilmasa daha iyi olur. printf() sorun ise muhtemlen sacma bir buffer sorunudur.

LEthaL
20/04/2003, 17:29
Bölümlendirmeyi ben yaptım. Sağol. Bilgi girisi için de islev yaparım ama clrscr() neden kullanmayayım?

Buffer sorununu nasıl halledebilirim?

Volkan Uzun
20/04/2003, 18:46
selamlar
kodu incelemedim ama calistirdim ve ne olursa olsun calisti
printf kaldırılsa bile calısıyor.
clrscr koymaman gerek cunku, bir programin kendinden önceki ekrani silmesi hos karsilanan bir davranis bicimi degildir

LEthaL
20/04/2003, 18:51
Çalışmasına şaşırdım. Kullandığın derleyici, editorü merak ettim. Sağol. Ben Borland C builer kullanıyorum ama printf(""); ler olmadan çalışmıyor

LEthaL
20/04/2003, 18:54
Sayıları bulmak için aralığı genişlettim gerekli tür dönüşümlerini de yaptım. Fakat en soldaki basamağı düşürmek için bir şey bulamadım. x%y işe yaramıyor sadece int ile sınırlı. Nasıl bir şey yapabilirim?

ee++
20/04/2003, 19:22
Mod islemi neden ise yaramasin? 311 % 100 -> 11 % 10 -> 1. Sanirim ne ile mod alman gerektigi acik, bence bir sorun yok gibi..

Ayrica sunu da belirteyim, 1 asal sayi degildir.

Eger modu kullanmazsan, sayıların denetimini bir dizgi (string) üzerinden sağlayabilirsin.

LEthaL
20/04/2003, 19:28
12345874440540 sayısının modunu nasıl alacağım?
Asal sayı yalnızca kendisine ve bire bölünebilen sayı değil mi?
String le denerim.

ee++
21/04/2003, 22:01
Soyle bir durum var: 12345874440540 sayisini zaten int ile tutamazsin. Hal boyle olunca mod islemini de yapamazsin tabi ki.. Yani 12345874440540 sayisini int ile bir sekilde islemeyi kafandan cikarman gerekiyor. (Tabi, long tipleri de denenebilir..)

Eger int'in sinirlari icinde islem yapmayi yeterli bulursan mod'da sorun yok zaten. Aksi takdirde dizgi kullanman gerekir.

"Tam olarak iki fakli (kendisi ve 1) doğal sayı böleni olan sayılara asal sayı denir." Sanirim bu tanim eksiksiz oldu.
Eger "Sadece kendisine ve 1'e bolunebilen sayilara asal sayi denir" klasik tanimini kullanmak istiyorsan, tanimin etki alanindan 1'i cikarman gerekiyor. Cunku 1 asal degildir.

Kolay gelsin.

LEthaL
21/04/2003, 22:13
Sağol. Dizgi kullanmayı deneyeceğim. Şu ara sınavlar bir geçsin. :|

acehreli
22/04/2003, 18:58
LEthaL, "programın çalışmaması" ile ne kasdettiğin tam olarak anlaşılmıyor. Program göçüyor mu, yoksa beklenen sonucu mu vermiyor? Programdan anladığım kadarıyla beklenen sonucu vermediğini söylüyorsun...

Önce şaka yanıt: 'main'in dönüş türü 'int' olmadığı için, bu standart bir C programı değildir. Derleyici kodu istediği gibi derleyebilir :) Gerçekten, 'void main' standart değildir; doğrusu 'int main'dir.

Benim görebildiklerim şunlar:

isPrime ve isSuperprime işlevlerinde kullanılan 'dur' değişkenlerine ilk değerleri atanmıyor. O işlevler de bazı durumlarda rastgele değerler döndürebiliyorlar. O işlevlerin çalıştırılmalarından önce başka işlevlerin çalıştırılıyor olmaları, yığıtta yaşayan bu 'dur' değişkenlerinin ilk değerlerini rastgele 0 veya başka bir şey yapabiliyor.

Ayrıca, konuyla ilgili olmasa da, 'main' içindeki değişkenleri 'static' yapmanın herhalde pek bir anlamı yok; çünkü 'main' işlevinin tekrar çağrılması söz konusu değildir.

Ali

ee++
22/04/2003, 20:02
'main' işlevi niye tekrar çağrılmasın? :)

acehreli
23/04/2003, 00:15
Düzeltme için teşekkürler, ee++. 'main'in program içinde çağrılamayacağını bir yerde duymuştum; ama neredeydi? :) google'da biraz aramayla sorunun yanıtını buldum:

Bir programın 'main'i çağırması

C'de yasal
C++'ta yasal değil

Düzeltir özür dileriz :)

groups.google.com'da şu aramayı yaparsanız bu soruyla ilgili bir konu çıkıyor:

"Can main () be called twice in the same program?"

Ali

ee++
23/04/2003, 10:12
"twice" ne demek.. "more than once" olmali.. :)

Forumuzun su konusu (http://forum.ceviz.net/showthread.php?s=&threadid=2715&perpage=20&pagenumber=8) altinda da belirttigim gibi, main() ilginc sekillerde kullanilabiliyor.

Hadi o kisma girmeyen arkadaslar icin buraya da ekliyeyim:

#include <stdio.h>
int l;int main(int o,char **O,
int I){char c,*D=O[1];if(o>0){
for(l=0;D[l ];D[l
++]-=10){D [l++]-=120;D[l]-=
110;while (!main(0,O,l))D[l]
+= 20; putchar((D[l]+1032)
/20 ) ;}putchar(10);}else{
c=o+ (D[I]+82)%10-(I>l/2)*
(D[I-l+I]+72)/10-9;D[I]+=I<0?0
:!(o=main(c/10,O,I-1))*((c+999
)%10-(D[I]+92)%10);}return o;}

:D

(Komut satirindan aldigi sayinin karekökünü hesaplayan programdır. Sadece çift haneli sayılar icin calisir; tek haneli sayilar icin sol basa bir 0 koymak yeterli olur.)

LEthaL
24/04/2003, 00:31
main() kullanılıyor benim bildiğim birden fazla ee++ dediği gibi;

#include <stdio.h>

void main(void)
{
int kar;
if( (kar=getchar()) != '\n' )
main();
putchar(kar);
}

çok güzel bir şey oluyor :)

ee++
24/04/2003, 00:50
main() int dondurmeli! void main() diye bir sey kesinlikle yok...

LEthaL
24/04/2003, 00:52
neden?

ee++
24/04/2003, 01:56
Cunku standart oyle tanimliyor. Zaten isletim sistemi de sizden bunu bekler. Isletim sistemi programin basari ile sonlandigini kendisine donen 0 degerinden anlar, 0 dan farkli degerler de cesitli hata kodlaridir. Ama en onemlisi, zaten void main() diye bir seyin olmadigi ve standardin int main() oldugudur.

(acehreli de deginmisti bu konuyu yukarida.)

LEthaL
24/04/2003, 10:48
Öğrendim. Sağolun. :)

ee++
24/04/2003, 21:56
Rica ederiz. ;)