تدريب عملي: خوارزميات المصفوفات والنصوص
تدريب عملي: خوارزميات المصفوفات والنصوص
وصلت إلى الدرس الأخير في هذا الفصل. كل ما تعلّمته — من توابع وحلقات ومصفوفات ونصوص — يجتمع هنا. لن نتعرّف على صياغة جديدة؛ بدلًا من ذلك سنتعلّم كيف نفكّر بأسلوب خوارزمي: نقرأ المسألة، ونختار بنية البيانات المناسبة، ثم نكتب كود Java سليمًا يستطيع أي زميل فهمه.
سنحلّ أربع مسائل كلاسيكية تظهر باستمرار في المقابلات الوظيفية، وتحدّيات البرمجة، والبرامج الفعلية:
- عكس مصفوفة في موضعها
- إيجاد القيمة الكبرى في مصفوفة
- حساب تكرارات حرف في نص
- التحقّق من أن نصًّا مقلوب (palindrome)
1. عكس مصفوفة في موضعها
العكس في الموضع يعني أنّنا لا ننشئ مصفوفة ثانية؛ بل نبادل العناصر داخل المصفوفة الأصلية. الأسلوب يُسمّى المؤشّران المتقابلان (Two-Pointer): مؤشّر يبدأ من الفهرس 0 وآخر من آخر فهرس، يتّجهان نحو بعضهما ويتبادلان العناصر حتى يلتقيا.
temp) وهو ثابت — O(1) space — ما يُفيد مع المصفوفات الكبيرة.
2. إيجاد القيمة الكبرى
النمط المعتاد: افترض أن العنصر الأوّل هو الحدّ الأقصى، ثم تجوّل بقيّة المصفوفة وحدّث افتراضك كلّما وجدت قيمة أكبر.
arr[0] على مصفوفة فارغة يرمي Java استثناءً من نوع ArrayIndexOutOfBoundsException في وقت التشغيل. فحص الطول مع رسالة خطأ واضحة يجعل التنقيح أسهل بكثير.
3. حساب تكرارات حرف
تخزّن كلاس String الأحرف مرتّبة. لحساب كم مرّة يظهر حرف معيّن، نمرّ على كل موضع باستخدام charAt(i) ونزيد عدّادًا عند التطابق.
'A' والحرف 'a' مختلفان في Java. إن أردت إحصاءً بغضّ النظر عن الحالة، حوّل النص والحرف المستهدف معًا إلى حالة واحدة أولًا: text.toLowerCase().charAt(i) وCharacter.toLowerCase(target).
4. التحقّق من كون النص مقلوبًا (Palindrome)
النص المقلوب يُقرأ بالاتّجاهَين بالطريقة ذاتها — مثل "racecar" و"level" و"madam". الأسلوب الأوضح يعكس تقنية عكس المصفوفة: قارن الحرف عند موضع left بالحرف عند موضع right. إذا تطابقت كل الأزواج حتى يلتقي المؤشّران، فالنص مقلوب.
replaceAll مع تعبير نمطي في البداية مرّة واحدة، تظل حلقة المقارنة بسيطة وتركّز على المهمّة الأساسية.
الأنماط المشتركة
لاحظ الأنماط المتكرّرة في الخوارزميات الأربع:
- المؤشّران المتقابلان — استُخدم في مسألتَي العكس والنص المقلوب. كلّما أردت مقارنة أو مبادلة من طرفَي تسلسل، تذكّر هذا النمط.
- النتيجة الجارية — استُخدم في مسألتَي الحدّ الأقصى والتعداد. هيّئ متغيّرًا قبل الحلقة، حدّثه داخلها، وأعده بعدها.
- الحراسة المبكّرة — تحقّق من الحالات الحدّية (مدخل فارغ، قيمة null) في أعلى التابع مباشرةً، ودع المسار الطبيعي يسير دون تشتّت دفاعي.
- الأسماء الوصفية للتوابع —
isPalindromeوfindMaxتخبر القارئ بما يفعله التابع قبل أن يقرأ سطرًا واحدًا من جسمه.
الخلاصة
في هذا الدرس نفّذت أربع خوارزميات أساسية من الصفر: عكس مصفوفة بأسلوب المبادلة بمؤشّرَين، وإيجاد الحدّ الأقصى بمتغيّر جارٍ، وعدّ الأحرف بمسح بسيط، والكشف عن النص المقلوب بمقارنة المؤشّرَين. هذه الأنماط تتكرّر في علم الحاسب طوال الوقت. أتقنها جيّدًا وستتعرّف عليها — أحيانًا في هيئة مختلفة — في مسائل أعقد بكثير في المستقبل.