Ekok bulma kodlarına bakabilir msiiniz?

Kodla Büyü

MEMEK

Süper Üye
Süper Üye
Mesajlar
1,436
Çalıştığım kitapta ekok bulma kodlarına baktım ama kodun bir türlü mantığını anlayamadaım. Bilen arsa izah edebilir mi?
// a be b ekok`u bulunacak sayılar
static int ekokBul(int a, int b)
{
int n;
for (n=1; ; n++)
{
if (n % a == 0 && n % b == 0)
return n;
}
}
 
kötü yazılmış bir kod ama yaptığı iş şu:
n değeri 1 den başlıyor bir bir artıyor. ne zaman ki n değeri hem a ya hem de b ye tam bölünüyorsa o zaman ekok odur diye return ediyor.
örnek a= 2 b=3 olsun iterasyon şu şekilde olacaktır. % mod anlamına gelir. bölme işleminden kalanı verir.

n=1
1%2 =1 ve 1%3 =1
n=2
2%2 =0 ve 2%3 =2
n=3
3%2 =1 ve 3%3 =0
n=4
4%2 =0 ve 4%3 =1
n=5
5%2 =1 ve 5%3 =2
n=6
6%2 =0 ve 6%3 =0 lduğundan ekok 6 dır.
 
Çalıştığım kitapta ekok bulma kodlarına baktım ama kodun bir türlü mantığını anlayamadaım. Bilen arsa izah edebilir mi?
// a be b ekok`u bulunacak sayılar
static int ekokBul(int a, int b)
{
int n;
for (n=1; ; n++)
{
if (n % a == 0 && n % b == 0)
return n;
}
}
Kodta dışarıdan gelen iki sayıyı n değişkenine tam bölünebilmesine bakılmış ve ilk tam bölünebilen n sayısını geri döndürmüş. For döngüsü ile 1 den başlayıp en küçük ortak kat bulana kadar bir arttırma işlemi yapmış.
 
kötü yazılmış bir kod ama yaptığı iş şu:
n değeri 1 den başlıyor bir bir artıyor. ne zaman ki n değeri hem a ya hem de b ye tam bölünüyorsa o zaman ekok odur diye return ediyor.
örnek a= 2 b=3 olsun iterasyon şu şekilde olacaktır. % mod anlamına gelir. bölme işleminden kalanı verir.

n=1
1%2 =1 ve 1%3 =1
n=2
2%2 =0 ve 2%3 =2
n=3
3%2 =1 ve 3%3 =0
n=4
4%2 =0 ve 4%3 =1
n=5
5%2 =1 ve 5%3 =2
n=6
6%2 =0 ve 6%3 =0 lduğundan ekok 6 dır.
Bende mantığını anlamış değildim şimdi anladım tşkler
 
kötü yazılmış bir kod ama yaptığı iş şu:
n değeri 1 den başlıyor bir bir artıyor. ne zaman ki n değeri hem a ya hem de b ye tam bölünüyorsa o zaman ekok odur diye return ediyor.
örnek a= 2 b=3 olsun iterasyon şu şekilde olacaktır. % mod anlamına gelir. bölme işleminden kalanı verir.

n=1
1%2 =1 ve 1%3 =1
n=2
2%2 =0 ve 2%3 =2
n=3
3%2 =1 ve 3%3 =0
n=4
4%2 =0 ve 4%3 =1
n=5
5%2 =1 ve 5%3 =2
n=6
6%2 =0 ve 6%3 =0 lduğundan ekok 6 dır.

Kötü yazılma sebebi nedir hocam?
 
ekok hiçbir zaman a veya b den küçük olamaz. o yüzden büyük olan n ye atanmalıydı. örnek 1000000 ile 10000001 sayılarının ekoku için gereksiz yere 1000000 iterasyon yapılır. bu kod için en küçük olan a veya b yi n ye atayıp döngüyü başlatmak gerekir.
 
ekok hiçbir zaman a veya b den küçük olamaz. o yüzden büyük olan n ye atanmalıydı. örnek 1000000 ile 10000001 sayılarının ekoku için gereksiz yere 1000000 iterasyon yapılır. bu kod için en küçük olan a veya b yi n ye atayıp döngüyü başlatmak gerekir.
Peki ekok u bulan kod nasıl olmalı?
 
using System;
public class Exercise45
{
public static void Main()
{
int i, n1, n2, max, lcm=1;
Console.Write("\n\n");
Console.Write("Determine the LCM of two numbers:\n");
Console.Write("-----------------------------------");
Console.Write("\n\n");
Console.Write("Input 1st number for LCM: ");
n1 = Convert.ToInt32(Console.ReadLine());
Console.Write("Input 2nd number for LCM: ");
n2 = Convert.ToInt32(Console.ReadLine());
max = (n1>n2) ? n1 : n2;
for(i=max; ; i+=max)
{
if(i%n1==0 && i%n2==0)
{
lcm = i;
break;
}
}
Console.Write("\nLCM of {0} and {1} = {2}\n\n", n1, n2, lcm);
}
}
 
ekok hiçbir zaman a veya b den küçük olamaz. o yüzden büyük olan n ye atanmalıydı. örnek 1000000 ile 10000001 sayılarının ekoku için gereksiz yere 1000000 iterasyon yapılır. bu kod için en küçük olan a veya b yi n ye atayıp döngüyü başlatmak gerekir.

Anladım hocam. Cevap için teşekkür ederim. Çeşitli kontroller eklenerek kodda iyileştirmeler yapılabilir elbette. Ancak amaç ekok hesaplatmak değil de programlama eğitimi olunca detaya girmiyorlar. Yoksa zamandan da epey tasarruf edilebilir dediğiniz gibi.

Ben algoritması kötü dediniz zannettim ve acaba ekok bulmanın başka bir yolu veya matematikçi yaklaşımı vardı da ben mi bilmiyorum diye düşündüm. Ki böyle temel problemlerle uğraşmayalı epey oldu.

Mesela her iki gönderide de verdiğiniz örnekler ardışık sayılardan oluşuyor. Ardışık sayılar aralarında asaldır ve aralarında asal iki sayının ekokları sayıların çarpımına eşittir. Böyle bir durum best case senaryo O(1) oluyor. Döngünün çalışmasına da gerek kalmıyor. Veya sayılar birbirine bölünüyorsa ortak kat büyük olan oluyor. Bu da O(1) zamanda bitirir işi. Ama buradaki algoritma worst case senaryoda bile lineer karmaşıklığa sahip, yani O(n) de çalışıyor. Bayağı verimli bir algoritma yani.

Not: Programcının zamanı bilgisayarın zamanından kıymetlidir. :D Ben kendi çalışmalarımda bayağı spagetti kod yazıyorum açıkçası. :oops:
 
Son düzenleme:
@buzdagi83 , @OgretmenBey Hocamlarım aşağıdaki koda bakabilir msiiniz?


static void Main(string[] args)
{
for (int i = 1; i < 11; i++)
Console.Write(Fibonacci(i) + " ");
Console.WriteLine();
Console.ReadKey();
}

static int Fibonacci(int n)
{
if (n < 2)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2); // Anlamadığım kod burası???
}
 
Anladım hocam. Cevap için teşekkür ederim. Çeşitli kontroller eklenerek kodda iyileştirmeler yapılabilir elbette. Ancak amaç ekok hesaplatmak değil de programlama eğitimi olunca detaya girmiyorlar. Yoksa zamandan da epey tasarruf edilebilir dediğiniz gibi.

Ben algoritması kötü dediniz zannettim ve acaba ekok bulmanın başka bir yolu veya matematikçi yaklaşımı vardı da ben mi bilmiyorum diye düşündüm. Ki böyle temel problemlerle uğraşmayalı epey oldu.

Mesela her iki gönderide de verdiğiniz örnekler ardışık sayılardan oluşuyor. Ardışık sayılar aralarında asaldır ve aralarında asal iki sayının ekokları sayıların çarpımına eşittir. Böyle bir durum best case senaryo O(1) oluyor. Döngünün çalışmasına da gerek kalmıyor. Veya sayılar birbirine bölünüyorsa ortak kat büyük olan oluyor. Bu da O(1) zamanda bitirir işi. Ama buradaki algoritma worst case senaryoda bile lineer karmaşıklığa sahip, yani O(n) de çalışıyor. Bayağı verimli bir algoritma yani.

Not: Programcının zamanı bilgisayarın zamanından kıymetlidir. :D Ben kendi çalışmalarımda bayağı spagetti kod yazıyorum açıkçası. :oops:

Öncelikle olayın farkındayım. Kodlamayı yeni öğrenirken buralara çok takılmamak lazım. Ama belli bir seviyeye geldiğinde karşımıza dediğiniz gibi best case worst case olayı çıkacak ve kod ne kadar kaliteli sorusu devreye girecek. Bu mevzularıda dikkate almak gerekir. Bu konuya dikkat çekmek için demiştim. Yoksa kitabın yazarı ilk seviye için yeterli bir kod örneği sunmuş. Yanlış anlaşılmak istemem.


Daha iyisi şöyle olabilir hocam. ebob * ekok = birinciSayi*ikinciSayi
denklemi yanlız bıraktığımızda ekok=birinciSayi*ikinciSayi / ebob

ebob ise O(n/2) ile bulunabilir. Dolayısıyla ekokta ~ O(n/2) bulunabilir.
 
@buzdagi83 , @OgretmenBey Hocamlarım aşağıdaki koda bakabilir msiiniz?


static void Main(string[] args)
{
for (int i = 1; i < 11; i++)
Console.Write(Fibonacci(i) + " ");
Console.WriteLine();
Console.ReadKey();
}

static int Fibonacci(int n)
{
if (n < 2)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2); // Anlamadığım kod burası???
}
Hocam bu sayı dizisi yazdırılırken bir önceki ve iki önceki ikisi sayının toplamı bulunurak hesaplanır. Özyinelemeli yöntemde n sayısı için n-1 ile n-2 toplanarak bulunuyor.
Burada kod ise şunu yapıyor.

i= 1 olsun
n=1 için
şu şekilde bir çalışma gerçekleşir
if (n < 2)
return n;​
// yukarıdaki koddan dolayı sonuç 1 çıkar yani Fibonacci(1) = 1 miş. bunu unutmayalım. Birazdan lazım olacağı için bu kısımda söyleyelim Fİbonacci(0) = 0 olur. (n= 0 için 0 döner.)
i= 2 olsun
n=2 için
//Burada else kısmı çalışır ve return ifadesi şu şekilde olur.
Fibonacci(1) + Fibonacci(0)
// Az önce bulmuştuk Fibonacci(1) =1 ve Fibonacci (0) =0 . Dolayısıyla 0+1 = 1 . Yani Fİbonacci (2) =1 miş.
i=3 için
n=3 için
//Burada else kısmı çalışır ve return ifadesi şu şekilde olur.
Fibonacci(2) + Fibonacci(1)
//Özyineleme olarak bunlar tekrarlanır. Metodu ayrı bir sayfada tekrar çalıştır.
//Fibonacci(2) yani yeni n=2 oldu ve bunun için metot tekrar çalışır.
Fibonacci(1) + Fibonacci(0) olur. burası 1 çıkar.​
//Şimdi Fibonacci(1) çalışır ve sonuç 1 çıkar. 1+1 = 2 olur.
// Yani Fibonacci (3) =2 olarak bulundu.
Bu böyle devam eder gider.

Fibonacci(4) sonucu için özyinelemeli metodun mantığı şu şekilde olacaktır.

Fibonacci(4) = ( Fibonacci(3) + Fibonacci(2) )
Fibonacci(4) = ( { Fibonacci(2) +Fibonacci(1) } + {Fibonacci(1)+ Fibonacci(0)} )
Fibonacci(4) = ( { [ Fibonacci(1)+Fibonacci(0) ] + Fibonacci(1) } + {Fibonacci(1)+ Fibonacci(0)} )

en alt satır artık sonuç kısmıdır.

Fibonacci(4) = ( { [ Fibonacci(1)+Fibonacci(0) ] + Fibonacci(1) } + {Fibonacci(1)+ Fibonacci(0) } )
Fibonacci(4) =( { [ 1 + 0 ] + 1 } + { 1 + 0 } )
Fibonacci(4) =( { 1 + 1 } + { 1 } )
Fibonacci(4) =( { 2 } + 1 )
Fibonacci(4) =( 2+ 1 )
Fibonacci(4) = 3


 
Hocam burayı bir türlü anlayamadım, açıklayabilir msiiniz?
max = (n1>n2) ? n1 : n2;
for(i=max; ; i+=max)
{
if(i%n1==0 && i%n2==0)
{


Ternary operatör olarak geçer. n1 n2'den büyükse max a n1 değişkeninin değerini at. Değilse n2 değişkeninin değerini at demektir.
Detaylı olarak şu şekilde:

max = (n1>n2) ? n1 : n2;

(n1> n2)? anlamı n1 n2 den büyük mü ? kısmı if anlamına gelir. Yani if(n1>n2) eşittir (n1> n2)?

doğru ise n1, max a atanır.
: bu işaret else anlamına gelir.
değilse n2 max a atanır.
 
Geri
Üst