الخوارزميات للمحترفين مدخل إلى الخوارزميات


محمد الميداوي

تُحدَّد مشكلةٌ خوارزميةٌ ما من خلال وصف المجموعة الكاملة للمدخلات -الحالات التطبيقية instances- التي يجب أن تعمل عليها المشكلة وكذلك مخرجاتها بعد العمل على إحدى تلك الحالات. واعلم أن التمييز بين المشكلة نفسها والحالة التطبيقية عليها instance مهم جدًا، فمثلًا، تُعرَّف المشكلة الخوارزمية المعروفة بالترتيب sorting على النحو التالي:

  • المشكلة: الترتيب.
  • المُدخلات: تسلسل من عدد n من المفاتيح ‎a_1, a_2, ..., a_n‎
  • الخرج: إعادة ترتيب تسلسل المدخلات بحيث يكون لدينا:
‎b_1, b_2,<= ... <= b_{n-1} <= b_n‎

قد تكون الحالة التطبيقية لمشكلة الترتيب instance of sorting أيّ تسلسل من العناصر، فقد تكون مصفوفةً من السلاسل النصية، مثل ‎{ Haskell; Emacs }‎ أو سلسلة من الأرقام، مثل: {154، 245، 1337}.

مثال على خوارزمية Fizz Buzz بسيطة في swift

يمهد هذا الدرس لكيفية كتابة الخورازميات في لغة Swift لمن لا يملك خبرة في هذه اللغة أو من أتى من خلفية برمجية مختلفة مثل بايثون أو جافا.

انظر سلسلة الأرقام التالية:

1 2 3 4 5 6 7 8 9 10

لعلك رأيت Fizz Buzz مكتوبة بهذه الصيغة أو FizzBuzz أو Fizz-Buzz، وجميعها تشير إلى نفس الشيء، وهذا "الشيء" هو محل النقاش هنا، لنبدأ بتعريف هاتين الكلمتين.

يشير المصطلحَان Fizz و Buzz إلى أيّ عدد مضاعف للعدد 3 أو 5 على الترتيب، أي إذا كان العدد يقبل القسمة على 3 فيمكن استبداله بـ fizz، وإذا كان قابلاً للقسمة على 5 فيُستبدل ب buzz. أما إذا كان من مضاعفات 3 و 5 فيُستبدَل بـ fizz buzz. أما المعنى الحرفي لهاتين الكلمتين فيشير إلى الصوت التي تحدثه كل كلمة منهما، وأصل استخدامها في هذا المثال يرجع للعبة أطفال شهيرة تُسمّى fizz buzz تقوم على نفس المبدأ.

لتنفيذ هذه الخوارزمية، افتح Xcode أو VS code (أو محرِّرك الذي تفضِّله) لإنشاء برنامج جديد وتهيئة مصفوفة من 1 إلى 5، ستكون 3 هي fizz هنا و 5 هي buzz، انظر:

let number  = [1,2,3,4,5]

هنا نمر على جميع عناصر المصفوفة للعثور على جميع قيم fizz و buzz، والتحقق ممّا إذا كانت العناصر من النوع fizz أو buzz، ولذا سننشئ حلقة for كما يلي:

for num in number {
 // الحسابات هنا
}

بعد هذا، سنستخدم العبارة الشرطية if else، وعامل الباقي module operator في لغة swift أي % لتحديد مواقع fizz و buzz.

for num in number {
 if num % 3 == 0 {
    print("\(num) fizz")
 } else {
    print(num)
 }
}

يكون الخرج الناتج:

1
2
3 fizz
4
5

سنضيف الآن الجزء المتعلق بالكلمة Buzz مستخدمين نفس التقنية:

for num in number {
 if num % 3 == 0 {
    print("\(num) fizz")
 } else if num % 5 == 0 {
    print("\(num) buzz")
 } else {
    print(num)
 }
}

سنزيد عناصر المصفوفة إلى 1-15. لاحظ أنّه بما أن 15 مضاعف لكلّ من 3 و 5، فينبغي استبدالها بـ fizz buzz:

for num in number {
 if num % 3 == 0 && num % 5 == 0 {
    print("\(num) fizz buzz")
 } else if num % 3 == 0 {
    print("\(num) fizz")
 } else if num % 5 == 0 {
    print("\(num) buzz")
 } else {
    print(num)
 }
}

ما تزال لدينا مشكلة قائمة، فالغرض الأساسي من الخوارزمية هو ترشيد وقت التنفيذ. تخيّل لو زدنا نطاق المصفوفة من 1-15 إلى 1-100، سيكون على المُصرِّف فحص كل عدد على حدة لتحديد ما إذا كان قابلاً للقسمة على 3 أو 5، ثمّ سيمرّ على الأعداد ثانية للتحقق ممّا إذا كانت قابلة للقسمة على 3 و5 (معًا)، كما سيتعيّن على الشيفرة أن تمرّ على كلّ عدد في المصفوفة مرّتين لأنّها ستتحقق من قابلية قسمة العدد على 3 أولًا، ثمّ على 5.

ولتسريع هذه العملية، يمكن أن نأمر المصرّف بقسمة الأعداد على 15 مباشرة. انظر الشيفرة النهائية:

for num in number {
 if num % 15 == 0 {
    print("\(num) fizz buzz")
 } else if num % 3 == 0 {
    print("\(num) fizz")
 } else if num % 5 == 0 {
    print("\(num) buzz")
 } else {
    print(num)
 }
}

هنئيًا لك، بهذا تكون قد كتبت أوّل خوارزمية لك، يمكنك استخدامها في أيّ لغة برمجة، وستعمل كما هو مُتوقّع.

ترجمة -بتصرّف- للفصل الأول من كتاب Algorithms Notes for Professionals.

اقرأ أيضًا





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن