الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

سؤال للتنشيط الذاكرة

مغلق
بدأه Ahmed H. Alawady في 5 يناير 2006 · 14 رد · 5,133 مشاهدة · في الرياضيات والخوارزميات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

إخوتي الأعزاء لقد مر علي أحد الأسئلة المنطقية في البرمجة ، وأحببت أن أضعها لما فيها من الفكرة البسيطة والجميلة

والحمد لله لقد قمت بحلها بطريقتين في 5 دقائق فقط

ودعونا نجعها مسابقة بسيطة جدا لتنشيط الذاكرة

وليس مهم صحة الكود فبأي كود يصح ، نحن لا نهتم بالكود ولكن نهتم بالفكرة

السؤال : عايزين نصل لهذه السلسلة ( 1 1 2 3 5 8 13 21......... )

والملاحظ أن البداية كانت برقم 1

والباقي هو أن 2 هو مجموع 1 1

3 هو مجموع 2 1

5 هو مجموع 3 2

8 هو مجموع 5 3

أي المضمون أن كل رقم هو مجموع الرقمين السابقين له وهكذا

نريد أن يتم عملها بأسلوبين : أحدهما حفظهما في الذاكرة والآخرى يتم طباعتها

ننتظر مشاركتكم في هذا ، وبالطبع نسأل الأخ الذي يريد الإستفادة أن لا يقرأ أجوبة الإخوة الآخرين لكي يستفيد

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#2

هذا ما يُسمى Fibonacci Series

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#3

السلام عليكم ورحمة الله

الأخ الكريم كل عام وانت طيب

على حد فهمى لكلام حضرتك , اليك الاثنين كود الاول للحفظ فى الذاكرة وكمان الطباعة . اما الثانى فيطبع الناتج ولكن لا يتم تخزين الا اخر قيمتين.

Dim x(100)
Let x(1)=1
print x(1)
for i =2 to 100
x(i)=x(i-1)+x(i-2)
print x(i)
end for
exit

     x1=1
1   x=x1+x0
     print x
     if x>1000 goto 2
     x0=x1
     x1=x
     goto 1
 2  exit

مع الاخذ فى الاعتبار انه من المعروف عند استخدام رمز لمتغير لم يتم تعريفه مسبقا , فان البرنامج يعتبر قيمته تساوى صفرا.

وشكرا,,,

أشهد أن لا إله إلا الله وأشهد أن محمدا رسول الله

bnr025.gif

مـــوقـــعـــى

#4

السلام عليكم

 int x = 1 , y = 1 , z;
     System.Console.Write(x +"  "+y+" ");
 	 for(int i =0; i < 8; i++)
 	 {
    z = x + y;
 	 System.Console.Write(z+" ");
    y = z - y;
    x = z;
 	 }
 	 System.Console.WriteLine();

ياريت يبقى كل أسبوع سؤال تشغيل مخ أحسن انا خايف بعد الامتحانات يجيلى تخلف عقلى وأنسى البرمجة خاااااااالص :lol:

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#5

بسم الله الرحمن الرحيم

القانون المستخدم لقاعدة Fibunanci

f(i)=F(i-1) + f(i-2)

بعد ذلك حول هذا القانون لديك الى كود برمجي

وجزاك الله اخي الكريم خيرا على هذه المعلومة المنشطة للذاكرة

#6

هذا السؤال في الخورزميات ولا علاقات لسي شارب به

يستخدم هذا السؤال عادة لتعليم المبتدئين اساسيات المعاودة

أضاعوني وأي فتى أضاعـوا * * * ليـوم كــريهـة وســـداد ثغــــر

وخـــــلونـي ومعتـرك المنايـا * * * وقد شـــرعوا أسنــتهم لنحـري

كأني لم أكــــــن فيهـم وسيطـا * * * ولم تك نســبتي في آل عمــرو

أجرر في الجـــوامع كـل يـوم * * * ألا لله مظــــلمتـي وهـصـــري

عسى الملك المجيب لمن دعاه * * * سينجيني فيعلم كيــف شكـري

فأجـــزي بالكرامـة أهـل ودي * * * وأجزي بالضـغينة أهل ضري

منتديات الرياضيات العربية

#7
basmla.gif

salam.gif

ما شاء الله أكابر المنتدى هما اللى بيردوا وبيشاركوا ، ده شرف عظيم مع إني كان الغرض من السؤال الناس المبتدئين علشان يتعلموا ولكن لا أرى أي تجاوب أصلا .

أولا بالنسبة لعلاقة المضوع بقسم السي شارب ، هو إني ياسيدي منتمي لقسمي ومتحيز له فقط :D .

ثانيا سبب كتابة هذا الموضوع أني أعرف شخصيا أشخاص مبرمجين ممتازين ولكن ليس لديهم القدرة على حل مثل هذه الأمثلة ولذلك اردنا أن نساعد بعضنا البعض .

أما بالنسبة لحل الكود بلغة السي شارب فهي كالتالي :

الطريقة الأولى وهي لحفظها في الذاكرة :

ArrayList list = new ArrayList();
list[0] = 1;
for(int i=0; i<100; i++)
{
int j, k;
if(i>0)    j = list[i-1];
else       j = 0;
// j = (i>0) ? list[i-1] : 0;
k = list + list[j];
list.Add(k);
}

وهذه الطريقة تتوقف بعد 100 خطوة

أما الطريقة الثانية وهي لطباعتها فورا بدون حفظها وهي بإسلوب O.O :

Class List
{
public int GetList()
{
int i=1, j=0, k;
k = i + j;
i = j
j = k
return k;
}
}

Class Print
{
List ll = new List();
while(true)
{
// this code with C++
printf("%d", ll.GetList());
//Or with C#
Consolr.WriteLine("{0}",ll.GetList());
}
}

أما هذه الطريقة فتعمل إلى مالانهاية

تم تعديل هذه المشاركة بواسطة Ahmed H. Alawady في 7 يناير 2006 في 07:58

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

#8

السلام عليكم

سبق ان طرح مثل هذا السؤال فى قسم vb.net وكان لى هذا الحل بعد ما لخبطت فى الاول

Dim num(10) As int32
Dim num2 As int32
For i As int32=1 To 10
Console.WriteLine((num(i-1)+num2).ToString)
num(i)=num2
num2+=num(i-1)
Next

/index.ph...topic=80622&hl=

VB.NET and C# Comparison

http://www.harding.edu/fmccown/vbnet_csharp_comparison.html

002.gif

=-=-=-=-=-=-=
ذو العلم يشقى فى النعيم بعلمه .:. واخو الجهالة فى الشقاوة ينعم
=-=-=-=-=-=-=
يا من بدنياه اشتغل . قد غره طول الأمل . فالموت يأتى بغتة . والقبر صندوق العمل
=-=-=-=-=-=-=
ان لم تستطع ان تجد ما تفعله فافعل ما لم تسطع ان تجده

screen_shot_2011-05-19_at_12.44.49_pm.pn

#9

......

الموضوع أسهل بهذه الطريقة كما أشار XHack بالأعلى...

اقتباس
بسم الله الرحمن الرحيم

القانون المستخدم لقاعدة Fibunanci

f(i)=F(i-1) + f(i-2)

بعد ذلك حول هذا القانون لديك الى كود برمجي

وجزاك الله اخي الكريم خيرا على هذه المعلومة المنشطة للذاكرة

وهي فقط هكذا:

public static int getByLevel(int level){
  if(level<=0)return 1;
  return getByLevel(level-1)+getByLevel(level-2);
	}

بعد ذلك تستطيع أن تنادي على أي حد: مثلا:

getByLevel(10)= 144
getByLevel(9)=  89
getByLevel(8)=  55
getByLevel(7)=  34
getByLevel(6)=  21
getByLevel(5)=  13
getByLevel(4)=  8
getByLevel(3)=  5
getByLevel(2)=  3
getByLevel(1)=  2
getByLevel(0)=  1

طبعا تستطيع استخدام هذه الطريقة لتخزين الأرقام في مصفوفة أو تطبعها مباشرة.. لاحظ أنك تستطيع أن تعرف أي حد بمناداة هذه الدالة، وهي ليست محصورة إلى 100 رقم أو غيره!

بالتوفيق!

#10

ممنوع استخدام المعاودة(الاستدعاء الذاتي ) لحل هذه المسالة بالذات ومسالة الفاكتوريال

تم تعديل هذه المشاركة بواسطة romanof في 12 يناير 2006 في 12:35

أضاعوني وأي فتى أضاعـوا * * * ليـوم كــريهـة وســـداد ثغــــر

وخـــــلونـي ومعتـرك المنايـا * * * وقد شـــرعوا أسنــتهم لنحـري

كأني لم أكــــــن فيهـم وسيطـا * * * ولم تك نســبتي في آل عمــرو

أجرر في الجـــوامع كـل يـوم * * * ألا لله مظــــلمتـي وهـصـــري

عسى الملك المجيب لمن دعاه * * * سينجيني فيعلم كيــف شكـري

فأجـــزي بالكرامـة أهـل ودي * * * وأجزي بالضـغينة أهل ضري

منتديات الرياضيات العربية

#11

الطريقة التي استعملها الأخ أبو مازن و هي تقنية الاستدعاء الذاتي جميلة لكنها خطيرة !!!!

عندما نريد ان نعرف ال Fibonacci لرقم مثل 20 فان الدالة تستدعي نفسها 21,891 مرة، اما اذا أردت حساب ال Fibonacci للرقم 30 فالدالة تستدعي نفسها حوالي 2,692,537 مرة و سيزداد هذا الرقم المهول بحوال 1,664,080 مرة اذا اردنا معرفة ال Fibonacci للرقم 31 ليصبح عدد مرات استدعاء الدالة لنفسها حوالي 4,356,617 !!!

و طبعا هذا أمر جد جد خطير على البرامج اذا لم يتم التعامل معه بحظر

و السلام عليكم

#12
crazy-man كتب:
الطريقة التي استعملها الأخ أبو مازن و هي تقنية الاستدعاء الذاتي جميلة لكنها خطيرة !!!!

عندما نريد ان نعرف ال Fibonacci  لرقم مثل 20 فان الدالة تستدعي نفسها 21,891 مرة، اما اذا أردت حساب ال Fibonacci  للرقم 30 فالدالة تستدعي نفسها حوالي 2,692,537 مرة و سيزداد هذا الرقم المهول بحوال 1,664,080 مرة اذا اردنا معرفة ال Fibonacci  للرقم 31 ليصبح عدد مرات استدعاء الدالة لنفسها حوالي 4,356,617 !!!

و طبعا هذا أمر جد جد خطير على البرامج اذا لم يتم التعامل معه بحظر

و السلام عليكم

لذلك انا افضل استخدام الloops عن استخدام التكرار

لانك تقوم ستقوم بالعديد من الحسابات الزائدة مثلا في الكود

f(i)=F(i-1) + f(i-2)

ستضطر الى حساب f(i-2 مرتين !! الاولى عند حسابها والثانية عند حساب الF(i-1) وهكذا عند كل مرحل من مراحل الاستدعاء لهذا كما اشار الcrazy-man :D فان عدد الحسايات (الفائضة) سيرتفع الى عدد هائل

بعكس استخدام الloops

procedure TForm1.Button1Click(Sender: TObject);
 var i,k,j,n,sum:integer;
     s:string;
begin
   n:=5;
   k:=1;
   j:=1;
   s:='1 1';
   for i:=3 to n  do
     begin
      sum:=k+j;
      s:=s+' '+IntToStr(sum);
      k:=j;
      j:=sum;
     end;
  Label1.Caption:=s;
end;

يعني لحساب العدد N فلن تحتاج الى اكتر من 3*(N-2) من الخطوات

تم تعديل هذه المشاركة بواسطة romanof في 12 يناير 2006 في 12:58

أضاعوني وأي فتى أضاعـوا * * * ليـوم كــريهـة وســـداد ثغــــر

وخـــــلونـي ومعتـرك المنايـا * * * وقد شـــرعوا أسنــتهم لنحـري

كأني لم أكــــــن فيهـم وسيطـا * * * ولم تك نســبتي في آل عمــرو

أجرر في الجـــوامع كـل يـوم * * * ألا لله مظــــلمتـي وهـصـــري

عسى الملك المجيب لمن دعاه * * * سينجيني فيعلم كيــف شكـري

فأجـــزي بالكرامـة أهـل ودي * * * وأجزي بالضـغينة أهل ضري

منتديات الرياضيات العربية

#13

ماذا لو فمنا بتنفبذ الخوارزميات الخاصة بالgraph مثلا اقصر طريق

او الmax flow

امكانية الوصول من عقدة الى اخرى وهكذا

أضاعوني وأي فتى أضاعـوا * * * ليـوم كــريهـة وســـداد ثغــــر

وخـــــلونـي ومعتـرك المنايـا * * * وقد شـــرعوا أسنــتهم لنحـري

كأني لم أكــــــن فيهـم وسيطـا * * * ولم تك نســبتي في آل عمــرو

أجرر في الجـــوامع كـل يـوم * * * ألا لله مظــــلمتـي وهـصـــري

عسى الملك المجيب لمن دعاه * * * سينجيني فيعلم كيــف شكـري

فأجـــزي بالكرامـة أهـل ودي * * * وأجزي بالضـغينة أهل ضري

منتديات الرياضيات العربية

#14

بعد مشاركة الأخ أيوب (crazy-man) وتوضيحه لمشكلة إعادة مناداة الدالة في طريقتي التي أدرجتها، وخلاصة الأمر أن الدالة قد تعيد حساب نفس الرقم عدة مرات حسب بُعدها عن رأس الهرم الشجري مما يطيل زمن حساب الناتج النهائي، بدأت أعيد النظر والبحث عن أفضل طريقة لحساب هذه السلسلة.

الطريقة الأولى مأخوذة من تعريف السؤال نفسه:

    public static long getBySlowRecursion(int level){
     	 if(level<=1)return 1;
  return getBySlowRecursion(level-1)+getBySlowRecursion(level-2);
	}

الطريقة السابقة بطيئة جدا لأنها تعيد حساب كثير من الأرقام لحساب رقم معين!

وبعد البحث وجدت ثلاث طرق ظريفة وسريعة ونبدأ بالأولى:

1- الطريقة المشابهة لطريقة المصفوفات المتبعة في السابق:

وهذه الطريقة تشبه أيضا عملية التبديل بين قيمتين Swap المعروفة:

	public static long getBySwapLikeArray(int level){
  long result1=0;
  long result2=1;
  for (int i = 0; i<level/2; i++){
 	 result1+=result2;
 	 result2+=result1;
  }
  return (level%2==0)?result1:result2;
	}

لاحظ أني أقسم التكرار على اثنين وأعيد قيمة result1 أو2 حسب حالة الحد إذا كان فرديا أو زوجيا!! لاحظ عملية قلب الرقمين في كل لفة!!

2- طريقة الدالة التي تعيد نفسها المتطورة: (هذه تطوير لعمليتي الأولى التي انتقدها الأخ أيوب)

وهذه تتفوق على عملية إعادة مناداة الدالة نفسها الأولى، ولكنها لا تعيد حساب الرقم المحسوب! وهو السبب في جعل الطريقة الأولى بطيئة.

	public static Pair getBySpecialRecursion(int level){
  if(level<=1)return DEFAULT;
  Pair p=getBySpecialRecursion(level-1);
  return new Pair(p.x+p.y, p.x);
	}
	static Pair DEFAULT=new Pair(1,1);
	static class Pair{
  long x,y;
  Pair(long x,long y){
 	 this.x=x;
 	 this.y=y;
  }
	}

كما ترى فهي عملية تنادي نفسها وكذلك تحتفظ بالرقم السابق. وتعيده إليك.

لاحظ أني تجنبت إعادة حساب الرقم المحسوب. وبهذه تكون هذه الدالة سريعة جدا! كما هو الحال مع قريناتها! لاحظ أني أنشئ Pairs كثيرة حسب عدد العد الذي أبحث عنه.

فهي تطبق نفس المعادلة f(x) = f(x-1) + f(x-2) لكن بتشكيل شجرة واحدة! ليست كالتي وضعتها في تعقيبي الأول.

وبهذا فإن أردت البحث عن الرقم أو الحد 20 فلن تنادي العملية 21,891 مرة ولكن فقط 20 مرة!!! وهذا فرق جذري كبير!

3- طريقة استعمال الرقم الذهبي!!!!!!!!

كنت أبحث عن دالة في المتسلسلات تعطيني الجواب مباشرة ، ولكني تفاجأت بوجود رقم ذهبي!! هذا ما يسمى الرقم الذهبي! وبعض الأحيان يسمى بالرقم الطبيعي ولا أقصد E أو e المعروف!

الرقم الذهبي والمربع الذهبي والسلسلة الذهبية أو Fibunanci هي أرقام ودوال رياضية تجدها موجودة حولك في الطبيعة، الموضوع يطول، وربما تدرسه لو كنت تدرس المتسلسلات أو تعمقت في الرياضيات. ولو كنت تريد الاستزادة فأنصحك بالبحث عن Golden Number أو Fibunanci.

ما علاقة هذا كله بهذه المتسلسلة؟ بتطبيق المعادلة التالية، تستطيع أن تحصل على الرقم في الحد الذي تريده:

    static double PHI1= (1 + Math.sqrt(5))/2;
    static double PHI2= (1 - Math.sqrt(5))/2;
	public static long getByUsingGoldingNumber(int level){
  long result = (long)((Math.pow((PHI1),level) - Math.pow(PHI2,level))/Math.sqrt(5));
  return result;
	}

لاحظ أني لا أستعمل تكرارا ولا أستعمل عملية تنادي نفسها! كل ما في الأمر أني أطبق المعادلة التي ترونها أمامكم. ربما تسألون عن الرقم الذهبي: تستطيع الحصول عليه بإجراء العملية PH1 أو PH2.

هذه هي الطرق الثلاث السريعة التي وجدتها، الأولى مشابهة لطريقة المصفوفات المتبعة في هذا الموضوع، والثاني تشبه موضوع العملية التي تنادي نفسها مع حل جذري لموضوع التكرار، والثالث هو معادلة مباشرة تعطي لك النتيجة.

حاولت أن أضع اختبارا للسرعة في حساب أول 100 باستعمال كل من العمليات الثلاث، لكن النتائج متقاربة، وأسرع عملية كانت باستعمال الرقم الذهبي، وهذا يتضح بسبب أنها معادلة مباشرة دون لف ولا دوران. والحائز على المرتبة الثانية كانت الطريقة الأولى، والحائز على المرتبة الثالثة كانت العملية التي تنادي نفسها المطورة.. وهي في المركز الثالث لأنك تحتاج إلى صناعة عدة مكونات عند حسابك لحد معين، فلو أردت حساب الحد رقم 50 فستحتاج إلى صناعة 50 شيء من الفئة Pair كما هو واضح في الشفرة. وجملة كل هذه الطرق تعتبر سريعة.

أطلت عليكم.

نلقاكم في موضوع آخر!

تم تعديل هذه المشاركة بواسطة أبومازن في 2 فبراير 2006 في 06:41

#15

السلام عليكم ورحمة الله وبركاته

لم أكن أتوقع أن تكون فكرة الموضوع محل إهتمام من الأخوة الأفاضل

فتخيلوا أن تكون الفكرة ليست زات معنى عندي ولكن أحببت أن نشارك بعضنا البعض فأصبحت الموضوع نشيط

فلو كل أخ كريم قدم موضوع يمكن يكون بالنسبة له لا شئ ولكن عسى أن يكون مصدر أهمية للجميع

فجزاكم الله خيرا

Name : Ahmed H. Alawady

Web Site : Alawady.info

Email : alawady_ahmed@hotmail.com

Tel : +2 012 345 6808

هذا الموضوع مغلق.

مواضيع مشابهة