C++ في العمق

البرنامج التعليمي للغة C++

تتناول الأقسام الأولى من هذا البرنامج التعليمي المواد الأساسية المعروضة في الوحدتين الأخيرتين، وتقدّم المزيد من المعلومات حول المفاهيم المتقدّمة. ينصب تركيزنا في هذه الوحدة على الذاكرة الديناميكية وعلى مزيد من التفاصيل حول الكائنات والفئات. ويتم أيضًا طرح بعض المواضيع المتقدّمة، مثل التوريث وتعدد الأشكال والنماذج والاستثناءات ومساحات الاسم. سندرسها لاحقًا في دورة Advanced C++.

تصميم موجه للأشياء

هذا برنامج تعليمي ممتاز حول التصميم الكائنات. سنطبّق المنهجية الموضّحة هنا في مشروع هذه الوحدة.

التعلم من خلال المثال رقم 3

ينصب تركيزنا في هذه الوحدة على اكتساب المزيد من التدريب باستخدام المؤشرات والتصميم الموجَّه للكائنات والمصفوفات المتعددة الأبعاد والفئات/العناصر. اطّلِع على الأمثلة التالية. لا يمكننا التأكيد بما فيه الكفاية على أنّ العامل الأساسي لكي تصبح مبرمجًا جيدًا هو التدرُّب والممارسة والممارسة.

التمرين الأول: مزيد من التدريب باستخدام المؤشرات

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

ما هو مُخرج البرنامج التالي؟ يُرجى عدم تشغيل البرنامج، مع رسم صورة من الذاكرة لتحديد الناتج.

void Unknown(int *p, int num);
void HardToFollow(int *p, int q, int *num);

void Unknown(int *p, int num) {
  int *q;

  q = #
  *p = *q + 2;
  num = 7;
}

void HardToFollow(int *p, int q, int *num) {
  *p = q + *num;
  *num = q;
  num = p;
  p = &q;
  Unknown(num, *p);
}

main() {
  int *q;
  int trouble[3];

  trouble[0] = 1;
  q = &trouble[1];
  *q = 2;
  trouble[2] = 3;

  HardToFollow(q, trouble[0], &trouble[2]);
  Unknown(&trouble[0], *q);

  cout << *q << " " << trouble[0] << " " << trouble[2];
}

بمجرد تحديد الإخراج يدويًا، قم بتشغيل البرنامج لمعرفة ما إذا كان صحيحًا أم لا.

التمرين الثاني: مزيد من التدريب باستخدام الفصول الدراسية والعناصر

إذا كنت بحاجة إلى تدريب إضافي على الفئات والكائنات، يمكنك الاطّلاع هنا على مرجع عن طريق تنفيذ فئتَين صغيرتَين. خصص بعض الوقت لأداء التمارين.

التمرين الثالث: الصفائف متعددة الأبعاد

ننصحك باستخدام البرنامج التالي: 

const int kStudents = 25;
const int kProblemSets = 10;

// This function returns the highest grade in the Problem Set array.
int get_high_grade(int *a, int cols, int row, int col) {
  int i, j;
  int highgrade = *a;

  for (i = 0; i < row; i++)
    for (j = 0; j < col; j++)
      if (*(a + i * cols + j) > highgrade)  // How does this line work?
        highgrade = *(a + i*cols + j);
  return highgrade;
}

int main() {
 int grades[kStudents][kProblemSets] = {
   {75, 70, 85, 72, 84},
   {85, 92, 93, 96, 86},
   {95, 90, 83, 76, 97},
   {65, 62, 73, 84, 73}
 };
 int std_num = 4;
 int ps_num = 5;
 int highest;

 highest = get_high_grade((int *)grades, kProblemSets, std_num, ps_num);
 cout << "The highest problem set score in the class is " << highest << endl;

 return 0;
}

هناك سطر في هذا البرنامج يحمل العنوان "كيف يعمل هذا السطر؟" - هل يمكنك معرفة ذلك؟ إليك شرحنا هنا.

اكتب برنامجًا يبدأ إعداد مصفوفة من 3 أبعاد ويملأ قيمة البُعد الثالث بمجموع الفهارس الثلاثة. إليك الحلّ الذي نقدّمه.

التمرين رقم 4: مثال على تصميم واسع النطاق خارج المنزل

إليك مثال مفصّل حول التصميم المرتكز على العناصر والذي يخضع للعملية برمتها من البداية إلى النهاية. تمت كتابة الرمز النهائي بلغة البرمجة Java، ولكن يمكنك الاطّلاع على الترميز الخاص به بناءً على التقدّم الذي أحرزته.

يُرجى قضاء بعض الوقت في العمل على هذا المثال بالكامل. هذا الفيديو هو رسم توضيحي رائع للعملية وبأدوات التصميم التي تدعمها.

اختبار الوحدات

مقدمة

الاختبار هو جزء مهم من عملية هندسة البرمجيات. اختبار الوحدات هو نوع معيّن من الاختبارات، يتحقّق من وظائف وحدة واحدة صغيرة من رمز المصدر.ويعمل المهندس دائمًا على إجراء اختبار الوحدات، ويتم إجراؤها عادةً في الوقت نفسه الذي يتم فيه ترميز الوحدة. وتُعد برامج تشغيل الاختبار التي استخدمتها لاختبار فئتَي Composer وقاعدة البيانات أمثلةً على اختبارات الوحدات.

تتسم اختبارات الوحدات بالخصائص التالية. هم...

  • اختبار مكون بشكل منفصل
  • حتمية
  • يتم تعيينها عادةً على فئة واحدة
  • تجنب التبعيات على الموارد الخارجية، مثل قواعد البيانات والملفات والشبكة
  • التنفيذ سريعًا
  • يمكن تشغيلها بأي ترتيب

هناك أُطر عمل ومنهجيات آلية توفّر الدعم والاتساق في اختبار الوحدات في مؤسسات هندسة البرمجيات الكبيرة. هناك بعض الأطر المتطورة والمفتوحة المصدر لاختبار الوحدات، والتي سنتعرّف عليها لاحقًا في هذا الدرس. 

وفي ما يلي شرح توضيحي للاختبارات التي تتم كجزء من اختبار الوحدات.

في عالم مثالي، نختبر ما يلي:

  1. يتم اختبار واجهة الوحدة للتأكُّد من تدفق المعلومات للداخل والخارج بشكل صحيح.
  2. يتم فحص هياكل البيانات المحلية للتأكد من أنها تخزن البيانات بشكل صحيح.
  3. يتم اختبار شروط الحدود للتأكّد من أنّ الوحدة تعمل بشكل صحيح في الحدود التي تحدّ من المعالجة أو تفرض قيودًا على المعالجة.
  4. نختبر المسارات المستقلة من خلال الوحدة للتأكّد من تنفيذ كل مسار، وبالتالي كل عبارة في الوحدة، مرة واحدة على الأقل. 
  5. وأخيرًا، نحتاج إلى التحقّق من التعامل مع الأخطاء بشكل صحيح.

عدد الرموز الترويجية

وفي الواقع، لا يمكننا تحقيق "تغطية كاملة للرموز" من خلال الاختبار. إنّ تغطية الرمز البرمجي هي طريقة تحليل تحدّد أجزاء النظام البرمجية التي تم تنفيذها (مغطّاة) بواسطة مجموعة حالة الاختبار والأجزاء التي لم يتم تنفيذها. وإذا حاولنا الحصول على تغطية كاملة بنسبة 100%، سنقضي وقتًا أطول في كتابة اختبارات الوحدات مقارنةً بكتابة الرمز البرمجي. وننصحك بابتكار اختبارات وحدات لكل المسارات المستقلة لما يلي. ويمكن أن يصبح ذلك بسرعة مشكلة هائلة.

في هذا المخطّط البياني، لا يتم اختبار الخطوط الحمراء بينما يتم اختبار الخطوط غير الملونة.

وبدلاً من محاولة توفير تغطية كاملة، نركّز على إجراء اختبارات تعزّز ثقتنا بأنّ الوحدة تعمل بشكل صحيح. نختبر عناصر مثل:

  • الحالات الخالية
  • اختبارات النطاق، مثل اختبارات القيمة الإيجابية/السلبية
  • الحالات الحدية
  • حالات التعذُّر
  • اختبار المسارات التي من المرجّح أن يتم تنفيذها في معظم الوقت

أطر اختبار الوحدة

تستخدم معظم إطارات عمل اختبار الوحدات تأكيدات لاختبار القيم أثناء تنفيذ مسار. التأكيدات هي عبارات تتحقق مما إذا كان الشرط صحيحًا. وقد تكون نتيجة هذا التأكيد نجاحها أو فشلها غير الفادح أو فشلها الفادح. وبعد التأكد من ذلك، يستمر البرنامج بشكل طبيعي إذا كانت النتيجة ناجحة أو فشلاً غير فادحة. وفي حالة حدوث فشل خطير، يتم إلغاء الوظيفة الحالية.

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

تحتوي حالة الاختبار على اختبار واحد أو أكثر. نحن نجمّع الاختبارات في حالات الاختبار التي تعكس بنية الرمز الذي تم اختباره. في هذه الدورة التدريبية، سنستخدم وحدة CPPUnit كإطار عمل لاختبار الوحدة. من خلال إطار العمل هذا، يمكننا كتابة اختبارات الوحدات في لغة C++ وتشغيلها تلقائيًا، مع تقديم تقرير حول نجاح الاختبارات أو فشلها.

تثبيت وحدة CPPUnit

نزِّل رمز CPPUnit من SourceForge. ابحث عن الدليل المناسب وضع ملف tar.gz هناك. بعد ذلك، أدخِل الأوامر التالية (في نظامَي التشغيل Linux وUnix) واستبدل اسم ملف وحدة cppunit المناسب:

gunzip filename.tar.gz
tar -xvf filename.tar

إذا كنت تستخدم نظام التشغيل Windows، قد تحتاج إلى العثور على أداة مساعدة لاستخراج ملفات tar.gz. الخطوة التالية هي تجميع المكتبات. التغيير إلى دليل cppunit. يوجد ملف INSTALL هناك يقدم إرشادات محددة. عليك عادةً تنفيذ ما يلي:

./configure
make install

إذا واجهت مشاكل، يُرجى الرجوع إلى ملف INSTALL. ويمكن العثور على المكتبات عادةً في الدليل cppunit/src/cppunit. للتأكّد من نجاح التجميع، انتقِل إلى cppunit/examples/simple Directory واكتب "make". إذا كانت كل المعلومات مجمّعة على ما يرام، لست بحاجة إلى تنفيذ أيّ إجراءات أخرى.

يمكنك الاطّلاع على برنامج تعليمي ممتاز هنا. يُرجى الاطّلاع على هذا البرنامج التعليمي وإنشاء فئة الرقم المركّب واختبارات الوحدات المرتبطة بها. هناك العديد من الأمثلة الإضافية في الدليل cppunit/examples.

لماذا يجب عليَّ القيام بذلك؟

يُعد اختبار الوحدات أمرًا بالغ الأهمية في الصناعة لعدة أسباب. سبق أن ذكرت سببًا واحدًا، وهو أنّنا نحتاج إلى طريقة للتحقّق من عملنا أثناء تطوير الرموز البرمجية. حتى عندما نطوّر برنامجًا صغيرًا جدًا، نكتب غريزيًا نوعًا ما من أدوات الفحص أو برامج التشغيل للتأكّد من أنّ البرنامج يقدّم ما هو متوقع.

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

باختصار، عند إرسال الرمز المكتمل لأول مرة إلى CVS، يعمل بشكل مثالي. وسيستمر في العمل بشكل مثالي لفترة من الوقت. وفي يوم من الأيام، غيّر شخص آخر الرمز الخاص بك. سيقوم أحد الأشخاص باختراق الرمز قريبًا أو لاحقًا. هل تعتقد أنهم سيلاحظون بأنفسهم؟ لا أعتقد ذلك. لكن عند كتابة اختبارات الوحدات، هناك أنظمة يمكنها تشغيلها تلقائيًا كل يوم. ويُطلق عليها اسم أنظمة التكامل المستمر. لذا عندما يكسر ذلك المهندس X الرمز البرمجي، سيرسل النظام رسائل إلكترونية بذيئة إلى أن يتم حلّ المشكلة. حتى لو كان المهندس "X" هو أنت.

بالإضافة إلى مساعدتك في تطوير البرامج، ثم الحفاظ على أمان هذه البرامج في مواجهة التغيير، واختبار الوحدات:

  • تنشئ هذه الأداة مواصفات قابلة للتنفيذ ووثائق تظل متزامنة مع الرمز. بمعنى آخر، يمكنك قراءة اختبار وحدة لمعرفة السلوك المتوافق مع الوحدة.
  • يساعدك على فصل المتطلبات عن التنفيذ. وبما أنّك تؤكّد السلوك الظاهر خارجيًا، تحظى بفرصة التفكير فيه بشكل صريح بدلاً من خلط الأفكار حول كيفية تنفيذ هذا السلوك.
  • تدعم إجراء التجارب إذا كانت لديك شبكة أمان لتنبيهك عندما تكون قد خالفت سلوك وحدة معيّنة، من المرجّح أن تجرّب عدة عناصر وتعيد ضبط تصميماتك.
  • يحسن تصميماتك. وغالبًا ما تتطلّب كتابة اختبارات وحدات شاملة جعل الرمز الخاص بك أكثر قابلية للاختبار. غالبًا ما يكون الرمز القابل للاختبار نمطيًا أكثر من الرموز غير القابلة للاختبار.
  • يحافظ على الجودة العالية. يمكن أن يؤدي خطأ صغير في نظام مهم إلى خسارة إحدى الشركات لملايين الدولارات، أو الأسوأ من ذلك، سعادة المستخدم أو ثقته. وتقلّل شبكة الأمان التي توفّرها الوحدة من هذا الاحتمال. ومن خلال اكتشاف الأخطاء مبكرًا، تتيح أيضًا لفرق ضمان الجودة قضاء الوقت في سيناريوهات الإخفاق الأكثر تعقيدًا وصعوبة، بدلاً من الإبلاغ عن الأعطال الواضحة.

خصص بعض الوقت لكتابة اختبارات الوحدة باستخدام CPPUnit لتطبيق قاعدة بيانات Composer. يُرجى الرجوع إلى الدليل cppunit/examples/ للمساعدة.

How Google works (طريقة عمل Google)

المقدمة

تخيَّل راهبًا من العصور الوسطى ينظر إلى آلاف المخطوطات في أرشيفات الدير."أين هذا الفنان لأرسطو؟..."

مكتبة الأديرة

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

يُطلق على نشاط تخزين المعلومات المكتوبة واستردادها من مجموعات كبيرة اسم استرجاع المعلومات (IR). وقد تزايدت أهمية هذا النشاط على مر القرون، لا سيما مع الاختراعات، مثل الورق والمطبعة. لقد كان في الماضي شيء لم يكن يشغل به سوى عدد قليل من الناس. ومع ذلك، يشارك مئات الملايين من المستخدمين اليوم في عملية استرجاع المعلومات كل يوم عندما يستخدمون أحد محرّكات البحث أو يبحثون في أجهزة الكمبيوتر المكتبي.

البدء في استرجاع المعلومات

قطة ذات قبعة

كتب الدكتور سوس 46 كتابًا للأطفال على مدار 30 عامًا. وكانت كُتبه تروي القطط والأبقار والأفيال وعن من وهم يضغطون جرسًا ولورا. هل تتذكر ما هي المخلوقات التي وردت في أي قصة؟ إذا لم تكن أحد الوالدَين، لن يتمكن أحد سوى الأطفال من إخبارك بمجموعة قصص "د. سوس" التي تضم المخلوقات التالية:

(COW وBEE) أو CROWS

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

أحد الأساليب الواضحة هي استخدام القوة الغاشمة: يمكنك الحصول على جميع قصص "دكتور سوس" التي يبلغ عددها 46 وبدء القراءة. ضَع في اعتبارك الكلمات التي تتضمّن الكلمتَين COW وBEE في كل كتاب، وابحث في الوقت نفسه عن الكتب التي تتضمّن كلمة CROWS. وتتّسم أجهزة الكمبيوتر بأنّها أسرع في هذا المجال. إذا كان لدينا كل النصوص من كتب الدكتور سوس في شكل رقمي، على سبيل المثال، كملفات نصية، يمكننا فقط البحث في الملفات عن طريق grep. وتنجح هذه التقنية في مجموعات صغيرة مثل كتب الدكتور سوس.

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

هناك طريقة أخرى إلى جانب grep، وهي إنشاء فهرس للمستندات ضمن مجموعة قبل إجراء البحث. ويكون الفهرس في الأشعة تحت الحمراء مشابهًا للفهرس المتوفّر في نهاية الكتاب الدراسي. ننشئ قائمة بجميع الكلمات (أو العبارات) في كل قصة من قصص الدكتور "سوس"، ونحذف بعض الكلمات مثل "ال" و"و" وحروف الجر وغيرها (وتُعرف هذه المصطلحات باسم كلمات التوقف). بعد ذلك، نمثّل هذه المعلومات بطريقة تسهّل العثور على المصطلحات والتعرّف على الأخبار التي تتضمنها.

ومن الأمثلة على ذلك مصفوفة تضمّ الأخبار في أعلى الصفحة والمصطلحات المدرَجة في كل صف. يشير الرقم "1" في العمود إلى أنّ العبارة تظهر في السجلّ الخاص بذلك العمود.

جدول الكتب والكلمات

يمكننا عرض كل صف أو عمود كمتجه بت. يشير خط متجه البت للصف إلى المقالات التي يظهر فيها المصطلح. يشير خط متجه البت في العمود إلى العبارات التي تظهر في السجلّ.

العودة إلى مشكلتنا الأصلية:

(COW وBEE) أو CROWS

نستخدم متجهات البت لهذه العبارات، ونجري أولاً إجراء استخدام حكيم البت للعبارات AND، ثم نعدّل ناتج OR ونستخدمه بطريقة بت.

(100001 و010011) أو 000010 = 000011

والإجابة هي: "السيد براون يمكنه مو! هل يمكنك؟" و"The Lorax". هذا رسم توضيحي لنموذج الاسترداد المنطقي، وهو نموذج "مطابقة تامة".

لنفترض أنّنا قرّرنا توسيع المصفوفة لتشمل جميع قصص الدكتور "سوس" وجميع المصطلحات ذات الصلة في هذه المقالات. ستنمو المصفوفة بشكل كبير، وستكون معظم الملاحظات المهمة 0. قد لا تكون المصفوفة أفضل تمثيل للفهرس. نحتاج إلى إيجاد طريقة لتخزين "1" فقط.

بعض التحسينات

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

إذا لم تكن معتادًا على استخدام القوائم المرتبطة، ما عليك سوى إجراء بحث على Google عن "القائمة المرتبطة بلغة C++ "، وستجد العديد من الموارد التي تصف كيفية إنشاء واحدة وكيفية استخدامها. سنتناول ذلك بمزيد من التفصيل في وحدة لاحقة.

يُرجى العلم أنّنا نستخدم معرّفات المستندات (DocIDs) بدلاً من اسم السجلّ. ونرتّب أيضًا معرّفات DocID هذه لأنّها تسهّل معالجة الطلبات.

كيف نعالج استعلامًا؟ بالنسبة إلى المشكلة الأصلية، نبحث أولاً عن قائمة منشورات COW، ثم قائمة منشورات BEE. ثم "ندمجها" معًا:

  1. احتفِظ بعلامات في كلتا القائمتين واطّلِع على قائمتَي المنشورات في الوقت نفسه.
  2. في كل خطوة، قارِن DocID الذي يشير إليه كلا المؤشرين.
  3. إذا كانا متماثلين، يمكنك وضع معرِّف المستند هذا في قائمة نتائج، وبخلاف ذلك تقدم المؤشر الذي يشير إلى معرّف docID الأصغر.

في ما يلي كيفية إنشاء فهرس معكوس:

  1. عيِّن مستند DocID لكل مستند يهمّك.
  2. لكل مستند، حدد المصطلحات ذات الصلة به (إنشاء رمز مميز).
  3. بالنسبة إلى كل عبارة، أنشئ سجلاً يتكون من العبارة وDocID حيث يتم العثور عليه، ومعدل تكرار في ذلك المستند. يُرجى العِلم أنّه قد تتوفّر سجلّات متعدّدة لعبارة معيّنة إذا ظهرت في أكثر من مستند واحد.
  4. رتِّب السجلّات حسب المصطلح.
  5. يمكنك إنشاء القاموس وقائمة المنشورات من خلال معالجة سجلات فردية لمصطلح ما، وكذلك دمج السجلات المتعددة للمصطلحات التي تظهر في أكثر من مستند واحد. أنشئ قائمة مرتبطة من DocIDs (بترتيب مرتَّب). ولكل عبارة أيضًا معدّل تكرار، وهو مجموع معدّل التكرار الوارد في كل السجلّات لعبارة ما.

المشروع

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

فيما يلي العملية الممكنة لإكمال هذا المشروع:

  1. أول شيء يجب القيام به هو تحديد استراتيجية لتحديد المصطلحات في الوثائق. ضَع قائمة بكل كلمات الإيقاف التي يمكنك التفكير فيها، واكتب دالة تقرأ الكلمات في الملفّات وتحفظ المصطلحات وتزيل عبارات التوقيف. قد تضطر إلى إضافة المزيد من كلمات الإيقاف إلى قائمتك أثناء مراجعة قائمة العبارات من تكرار تحسيني.
  2. يمكنك كتابة حالات اختبار CPPUnit لاختبار الدالة، وإنشاء ملف إنشاء لتجميع كل شيء معًا من أجل تصميمك. راجِع ملفاتك في CVS، لا سيّما في حال العمل مع شركاء. قد ترغب في البحث عن طريقة فتح مثيل CVS أمام المهندسين عن بُعد.
  3. عند إضافة عملية المعالجة لتضمين بيانات الموقع الجغرافي، أي ملف وأين يقع المصطلح في الملف؟ قد تحتاج إلى إجراء عملية حسابية لتحديد رقم الصفحة أو رقم الفقرة.
  4. كتابة حالات اختبار CPPUnit لاختبار هذه الوظيفة الإضافية.
  5. أنشئ فهرسًا معكوسًا وخزِّن بيانات الموقع الجغرافي في سجل كل عبارة.
  6. كتابة المزيد من حالات الاختبار.
  7. تصميم واجهة للسماح للمستخدم بإدخال استعلام.
  8. باستخدام خوارزمية البحث الموضّحة أعلاه، عالِج الفهرس المعكوس وعرض بيانات الموقع الجغرافي للمستخدم.
  9. تأكد من تضمين حالات الاختبار لهذا الجزء الأخير أيضًا.

كما فعلنا في جميع المشاريع، يمكنك الاستعانة بالمنتدى والمحادثة للعثور على شركاء المشروع وتبادل الأفكار.

ميزة إضافية

تُعرف خطوة المعالجة الشائعة في العديد من أنظمة الأشعة تحت الحمراء باسم الاشتقاق. والهدف الأساسي من المشتقات هو أن المستخدمين الذين يبحثون عن معلومات حول "استرداد البيانات" سيهتمون أيضًا بالمستندات التي تحتوي على معلومات تشمل "استرداد" و"تم استرداده" و"استرجاعه" وما إلى ذلك. وقد تكون الأنظمة عرضة للأخطاء بسبب ضعف الجذور، وبالتالي هذه العملية قد تكون صعبة. على سبيل المثال، قد يحصل المستخدم المهتم بـ "استرجاع المعلومات" على مستند بعنوان "معلومات عن Golden ريتريفر" بسبب اشتقاقه. من بين الخوارزميات المفيدة للاشتقاق خوارزمية بورتر.

التطبيق: انتقِل إلى أي مكان.

اطلع على هذا تطبيق لهذه المفاهيم على Panoramas.dk.