تخطَّ إلى المحتوى
ARAB CODEمجتمع المطورين العرب

الخوارزميات والشيفرة الزائفة: فكّر في الحل قبل أن تكتب الكود

درسنُشر ٢٤ أكتوبر ٢٠٢٦ · 0 رد · 1 مشاهدة#خوارزميات#شيفرة-زائفة#تعقيد#مبتدئ
قبل ساعتين

مقدمة

الخوارزمية هي سلسلة خطوات محددة تحل مشكلة وتنتهي. قبل أن تختار اللغة أو المكتبة، تحتاج أن تعرف ما الخطوات. كثير من المبتدئين يبدأون بالكتابة مباشرة ثم يتوهون؛ والمحترفون يكتبون الحل أولاً بلغة بشرية منظمة تسمى الشيفرة الزائفة (Pseudocode).

أهداف التعلم

  • تعريف الخوارزمية وصفاتها: مدخلات، مخرجات، خطوات واضحة، انتهاء.
  • كتابة شيفرة زائفة مقروءة.
  • تحويل الشيفرة الزائفة إلى كود فعلي.
  • تقدير الكفاءة بتعقيد Big-O على مستوى أساسي.

1. مثال: البحث عن أكبر رقم في قائمة

بالكلام: «احفظ أول رقم على أنه الأكبر. مرّ على بقية الأرقام؛ إن وجدت رقماً أكبر احفظه. في النهاية أعد المحفوظ.»

بالشيفرة الزائفة:

دالة أكبر_عنصر(قائمة):
    إذا كانت القائمة فارغة:
        أعد «لا يوجد»
    الأكبر ← قائمة[0]
    لكل عنصر في قائمة بدءاً من الثاني:
        إذا كان عنصر > الأكبر:
            الأكبر ← عنصر
    أعد الأكبر

لاحظ أننا عالجنا حالة القائمة الفارغة قبل أي شيء — هذه «الحالات الحدية» مصدر معظم الأخطاء.

2. من الشيفرة الزائفة إلى الكود

def max_item(items):
    if not items:
        return None
    largest = items[0]
    for x in items[1:]:
        if x > largest:
            largest = x
    return largest

print(max_item([4, 17, 9, 17, 2]))  # 17
print(max_item([]))                 # None

التحويل شبه مباشر لأن التفكير حدث مسبقاً.

3. البحث الثنائي: خوارزمية أذكى لبيانات مرتبة

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

دالة بحث_ثنائي(قائمة_مرتبة، هدف):
    يسار ← 0 ، يمين ← طول(القائمة) - 1
    طالما يسار ≤ يمين:
        وسط ← (يسار + يمين) ÷ 2 مقربة للأسفل
        إذا قائمة[وسط] = هدف: أعد وسط
        إذا قائمة[وسط] < هدف: يسار ← وسط + 1
        وإلا: يمين ← وسط - 1
    أعد -1
function binarySearch(sorted, target) {
  let lo = 0, hi = sorted.length - 1;
  while (lo <= hi) {
    const mid = Math.floor((lo + hi) / 2);
    if (sorted[mid] === target) return mid;
    if (sorted[mid] < target) lo = mid + 1;
    else hi = mid - 1;
  }
  return -1;
}
console.log(binarySearch([1, 3, 5, 7, 9, 11], 7)); // 3

4. Big-O: كيف ينمو الوقت مع حجم البيانات؟

  • البحث عن الأكبر يمر على كل العناصر مرة: O(n) — إن تضاعف حجم القائمة تضاعف الوقت تقريباً.
  • البحث الثنائي يقسم المسافة على 2 في كل خطوة: O(log n) — مليون عنصر يحتاج نحو 20 مقارنة فقط.
  • مقارنة كل عنصر بكل عنصر آخر (حلقتان متداخلتان): O(n²) — تصبح بطيئة جداً مع البيانات الكبيرة.

Big-O يصف معدل النمو وليس الزمن الفعلي بالثواني؛ ويتجاهل الثوابت. لذلك قد تكون خوارزمية O(n) أبطأ من O(n log n) على بيانات صغيرة، لكنها تتفوق مع ازدياد الحجم.

تمرين عملي

  1. اكتب شيفرة زائفة لدالة تحسب عدد مرات ظهور رقم معين في قائمة، ثم حولها إلى كود.
  2. اكتب دالة تتحقق هل في القائمة رقمان مكرران. الحل الأول بحلقتين متداخلتين (O(n²))، ثم حسّنه باستخدام مجموعة (Set) ليصبح O(n) تقريباً.
  3. جرّب البحث الثنائي على قائمة غير مرتبة ولاحظ لماذا تفشل النتيجة.

أخطاء شائعة

  • نسيان الحالات الحدية: القائمة الفارغة، عنصر واحد، القيم المكررة، الأرقام السالبة.
  • الحلقات التي لا تنتهي: في البحث الثنائي، استخدام lo = mid بدلاً من mid + 1 قد يجعل الحلقة تدور إلى الأبد.
  • التحسين المبكر: اكتب حلاً صحيحاً وواضحاً أولاً، ثم قِس، ثم حسّن ما يستحق.

الخلاصة

اكتب الحل بخطوات واضحة قبل الكود، اختبر الحالات الحدية، واستخدم Big-O لتقدير سلوك حلك عندما تكبر البيانات. هذه العادة وحدها توفر عليك ساعات من تصحيح الأخطاء.

مصادر مقترحة

  • كتاب Grokking Algorithms لـ Aditya Bhargava.
  • موقع VisuAlgo لعرض الخوارزميات بصرياً.
  • مسائل تحديات عرب كود في تصنيف «الخوارزميات» للتطبيق.

الرد على الموضوع

سجّل الدخول للمشاركة في النقاش.

نقاشات مشابهة