تمرين من المصدر الأصلي · تطبيق عملي

تعدد

استخدم الشرح العربي للفهم، واعتمد صفحة CS50 الأصلية مرجعًا نهائيًا للمواصفات والتسليم.

جلسة دراسة مقترحة: حتى 60 دقيقةالجهد الكلي التقريبي: 120 دقيقة · أكمل من حيث توقفت لاحقًا.Week 3
محاور هذه الخطوة
  • البحث
  • الترتيب
  • الاستدعاء الذاتي
  • Big O

ترجمة آلية تحت المراجعة

تعدد

المصدر الأصلي

قائمة تنفيذ التمرين

تُحفظ علامات هذه القائمة على هذا الجهاز والمتصفح فقط. أنشئ حسابًا مفعّلًا لحفظ إنجاز التمرين في مسارك.

تعدد

مشكلة بحاجة إلى حل

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

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

بالنسبة لهذه المشكلة، عليك تنفيذ برنامج يجري انتخابات تعددية، وفقًا لما يلي.

تجريبي

رمز التوزيع

بالنسبة لهذه المشكلة، ستقوم بتوسيع وظيفة "رمز التوزيع" المقدمة لك من قبل موظفي CS50.

قم بتنزيل كود التوزيع

قم بتسجيل الدخول cs50.dev، انقر على نافذتك الطرفية، وقم بالتنفيذ cd بمفرده. يجب أن تجد أن مطالبة النافذة الطرفية الخاصة بك تشبه ما يلي:

$

التنفيذ التالي

wget https://cdn.cs50.net/2026/x/psets/3/plurality.zip

من أجل تنزيل ملف ZIP يسمى plurality.zip في مساحة الشيفرة الخاصة بك.

ثم نفذ

unzip plurality.zip

لإنشاء مجلد يسمى plurality. لم تعد بحاجة إلى ملف ZIP، حتى تتمكن من التنفيذ

rm plurality.zip

ثم قم بالرد بـ "y" متبوعًا بـ Enter عند المطالبة لإزالة ملف ZIP الذي قمت بتنزيله.

الآن اكتب

cd plurality

متبوعًا بـ Enter للانتقال إلى (i.e.، open) هذا الدليل. يجب أن تشبه مطالبتك الآن ما يلي.

plurality/ $

إذا كان كل شيء ناجحًا، فيجب عليك التنفيذ

ls

وشاهد الملف المسمى plurality.c. تنفيذ code plurality.c الملف الذي ستكتب فيه الشيفرة الخاص بك لمجموعة المشكلات هذه. إذا لم يكن الأمر كذلك، قم بإعادة تتبع خطواتك ومعرفة ما إذا كان بإمكانك تحديد الخطأ الذي ارتكبته!

فهم الشيفرة الموجود plurality.c

عندما تقوم بتوسيع وظيفة الشيفرة الموجودة، فمن الأفضل التأكد من أنك تفهمها أولاً في حالتها الحالية.

انظر أولاً إلى أعلى الملف. الخط #define MAX 9 هو بعض بناء الجملة المستخدم هنا للإشارة إلى ذلك MAX هو ثابت (يساوي 9) التي يمكن استخدامها خلال البرنامج. ويمثل هنا الحد الأقصى لعدد المرشحين الذين يمكن أن تضمهم الانتخابات. يستخدم

// Max number of candidates
#define MAX 9

لاحظ ذلك تم الآن إنشاء plurality.c بعد ذلك هذا الثابت لتعريف مصفوفة عامة — أي مصفوفة يمكن لأي دالة الوصول إليها.

// Array of candidates
candidate candidates[MAX];

لكن ما هو، في هذه الحالة، أ candidate؟ في plurality.c، أ candidate هو أ struct. كل يحتوي candidate على حقلين: أ string name يمثل اسم المرشح، و int votes يمثل عدد الأصوات التي حصل عليها المرشح.

// Candidates have name and vote count
typedef struct
{
    string name;
    int votes;
}
candidate;

الآن، ألق نظرة على main تعمل بنفسها. معرفة ما إذا كان يمكنك العثور على المكان الذي يقوم فيه البرنامج بتعيين متغير عام candidate_count يمثل عدد المرشحين في الانتخابات.

// Number of candidates
int candidate_count;

ماذا عن مكان نسخ وسيطات سطر الأوامر إلى المصفوفة candidates?

// Populate array of candidates
candidate_count = argc - 1;
if (candidate_count > MAX)
{
    printf("Maximum number of candidates is %i\n", MAX);
    return 2;
}
for (int i = 0; i < candidate_count; i++)
{
    candidates[i].name = argv[i + 1];
    candidates[i].votes = 0;
}

وأين يطلب من المستخدم كتابة عدد الناخبين؟

int voter_count = get_int("Number of voters: ");

بعد ذلك، يتيح البرنامج لكل ناخب كتابة تصويت، من خلال الاتصال بـ vote وظيفة لكل مرشح تم التصويت له. وأخيرا، يقوم main بإجراء اتصال بـ وظيفة print_winner لطباعة الفائز (أو الفائزين) في الانتخابات. سنترك الأمر لك لتحديد الشيفرة الذي ينفذ هذه الوظيفة.

إذا نظرت إلى أسفل الملف، فستلاحظ أن تم ترك وظائف vote و print_winner فارغة.

// Update vote totals given a new vote
bool vote(string name)
{
    // TODO
    return false;
}

// Print the winner (or winners) of the election
void print_winner(void)
{
    // TODO
    return;
}

هذا الجزء متروك لك لإكماله! يجب ألا تقوم بتعديل أي شيء آخر في plurality.c بخلاف تطبيقات وظائف vote و print_winner (وإدراج ملفات رأس إضافية، إذا كنت ترغب في ذلك).

تلميحات

انقر على أزرار التبديل أدناه لقراءة بعض النصائح!

أكمل وظيفة vote

بعد ذلك، أكمل vote .

  • فكر في ذلك توقيع vote، bool vote(string name)، يوضح أن الأمر يتطلب وسيطة واحدة، أ string name، يمثل اسم المرشح الذي تم التصويت له.
  • vote يجب أن يُرجع أ bool، حيث true يشير إلى أنه تم الإدلاء بالتصويت بنجاح و false يشير إلى أنه لم يكن كذلك.

إحدى الطرق لحل هذه المشكلة هي القيام بما يلي:

  1. قم بالتكرار على كل مرشح
    1. تحقق مما إذا كان اسم المرشح يطابق الإدخال، name
      1. إذا كانت الإجابة بنعم، قم بزيادة أصوات ذلك المرشح والعودة true
      2. إذا كانت الإجابة لا، فتابع التحقق
  2. في حالة عدم وجود تطابقات بعد التحقق من كل مرشح، قم بالرجوع false

دعنا نكتب بعض الرموز الزائفة لتذكيرك بفعل ذلك:

// Update vote totals given a new vote
bool vote(string name)
{
    // Iterate over each candidate
        // Check if candidate's name matches given name
            // If yes, increment candidate's votes and return true

    // If no match, return false
}

سنترك التنفيذ بالشيفرة، الأمر متروك لك!

أكمل وظيفة print_winner

أخيرًا، أكمل print_winner .

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

قد تعتقد أن خوارزمية الفرز هي الأفضل لحل هذه المشكلة: تخيل فرز المرشحين حسب إجمالي أصواتهم وطباعة المرشح الأعلى (أو المرشحين). تذكر، مع ذلك، أن الفرز يمكن أن يكون مكلفًا: فحتى Merge Sort، وهي إحدى أسرع خوارزميات الفرز، تعمل في \(O(N \space log(N))\).

ضع في اعتبارك أنك تحتاج إلى معلومتين فقط لحل هذه المشكلة:

  1. الحد الأقصى لعدد الأصوات
  2. المرشح (أو المرشحين) الحاصلين على هذا العدد من الأصوات

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

// Print the winner (or winners) of the election
void print_winner(void)
{
    // Find the maximum number of votes

    // Print the candidate (or candidates) with maximum votes

}

سنترك الشيفرة لك!

الإرشادات التفصيلية

محتوى خارجي من YouTube

لن نتصل بهذه الخدمة قبل موافقتك. يمكنك فتح المصدر في نافذة مستقلة بدل تحميله هنا.

فتح المصدر

كيفية الاختبار

تأكد من اختبار الشيفرة الخاص بك للتأكد من أنه يتعامل مع...

  • انتخابات بأي عدد من المرشحين (حتى MAX من 9)
  • التصويت للمرشح بالاسم
  • أصوات غير صالحة للمرشحين غير الموجودين في بطاقة الاقتراع
  • طباعة الفائز في الانتخابات إذا كان هناك واحد فقط
  • طباعة الفائز في الانتخابات إذا كان هناك عدة فائزين

صحة

check50 cs50/problems/2026/x/plurality

النمط

style50 plurality.c

كيفية الإرسال

في جهازك الطرفي، قم بتنفيذ ما يلي لإرسال عملك، والإجابة على المطالبات التي تظهر أيضًا.

submit50 cs50/problems/2026/x/plurality

أنهيت التطبيق؟

راجع عناصر التنفيذ أعلاه، ثم احفظ إنجازك وانتقل إلى التمرين التالي.

حفظ إنجاز التمرين

يمكنك قراءة الدورة كاملة دون حساب. يصبح حفظ التقدم متاحًا بعد تفعيل الحساب، ويبقى محفوظًا بعد انتهاء العضوية.

العودة إلى جميع التمارين