مقدمة: السؤال الأبدي "هل هذا موجود هنا؟"
تخيل: أنت تكتب لعبة بلغة C++ حيث تحتاج إلى التحقق مما إذا كان اللاعب يمتلك مفتاحًا في المخزون. أو تعمل على نظام تسجيل - تحتاج للتأكد من أن رسالة بهذا المعرف لم تتم معالجتها بعد. أو ببساطة تقوم بواجب منزلي في البرمجة. وفجأة - توقف. كيف، بحق الجحيم، يمكنك معرفة بسرعة ما إذا كان العنصر موجودًا في std::vector؟
هذا السؤال هو أحد أكثر الأسئلة شيوعًا على Stack Overflow (عشرات الآلاف من المشاهدات!). وليس بدون سبب. std::vector هو حصان العمل في C++، لكنه لا يحتوي على طريقة مدمجة .contains() كما في Python أو C#. غالبًا ما يضيع المبتدئون. المحترفون - يضيعون الوقت في اختيار الطريقة المثلى.
في هذه المقالة، سنستعرض جميع الطرق الرئيسية للتحقق من وجود عنصر في المتجه: من الأبسط والأكثر وضوحًا إلى الحيل الذكية مع البحث الثنائي. ستعرف أي طريقة تستخدمها ومتى، ولن تضطر أبدًا للتخمين مرة أخرى. هيا بنا!
الطريقة 1: الكلاسيكية - std::find
الطريقة الأكثر مباشرة ووضوحًا هي استخدام خوارزمية std::find من ملف الرأس <algorithm>. تعمل مع أي نوع بيانات يدعم عامل المقارنة ==.
المنطق بسيط: std::find يمر عبر المتجه من البداية إلى النهاية ويعيد مكررًا (iterator) إلى أول عنصر يتم العثور عليه. إذا لم يتم العثور على العنصر، فإنه يعيد vector.end().
مثال الكود:
#include <iostream>#include <vector>#include <algorithm> // لـ std::find
int main() { std::vector<int> numbers = {10, 20, 30, 40, 50}; int target = 30;
// نبحث عن العنصر auto it = std::find(numbers.begin(), numbers.end(), target);
if (it != numbers.end()) { std::cout << "تم العثور على العنصر " << target << "! (الفهرس: " << std::distance(numbers.begin(), it) << ")" << std::endl; } else { std::cout << "لم يتم العثور على العنصر " << target << "." << std::endl; } return 0;}الإيجابيات: البساطة، الوضوح، يعمل مع أي نوع (int, string, الهياكل الخاصة بك).
السلبيات: التعقيد الخطي O(n). إذا كان المتجه كبيرًا (ملايين العناصر)، وكنت تبحث بشكل متكرر - فهذا بطيء.
الطريقة 2: عد التكرارات - std::count
أحيانًا لا تحتاج فقط إلى معرفة "موجود أم لا"، بل تريد معرفة عدد مرات ظهور العنصر. لهذا، std::count مثالي. وهو أيضًا من <algorithm>.
مثال الكود:
#include <iostream>#include <vector>#include <algorithm>
int main() { std::vector<std::string> fruits = {"apple", "banana", "apple", "orange"}; std::string target = "apple";
int count = std::count(fruits.begin(), fruits.end(), target);
if (count > 0) { std::cout << "تم العثور على الفاكهة '" << target << "' " << count << " مرة (مرات)." << std::endl; } else { std::cout << "الفاكهة غير موجودة." << std::endl; } return 0;}الإيجابيات: يعطي عدد التكرارات. بسيط جدًا أيضًا.
السلبيات: نفس التعقيد الخطي O(n). إذا كنت تحتاج فقط إلى "نعم/لا"، فإن std::find يمكنه التوقف عند أول تطابق، بينما std::count سيمر عبر المتجه بأكمله. لذلك، للتحقق من الوجود، std::find أسرع قليلاً.
الطريقة 3: الفرز + البحث الثنائي (للمحترفين)
إذا كنت تبحث عن عناصر في نفس المتجه عدة مرات، فقد حان الوقت للانتقال إلى المستوى التالي. قم بفرز المتجه مرة واحدة واستخدم std::binary_search. التعقيد - لوغاريتمي O(log n). هذا أسرع بكثير على البيانات الكبيرة.
شرط مهم:
يجب أن يكون المتجه مفرزًا