تعقيد المثال القياسي

لا تقدم المكتبة القياسية C ++ مجموعة من الفئات فحسب ، بل تحدد أيضًا كيفية كتابة البرامج. تتناول هذه المقالة المتطلبات العامة لتنفيذ البرامج باستخدام STL.

النظر في المهمة التالية:
اقرأ مجموعة من الأعداد الصحيحة مفصولة بمسافة بيضاء من ملف input.txt. فرزها والكتابة إلى output.txt

يمكنك كتابة الحل التالي:

#include <vector> #include <algorithm> #include <fstream> int main(){ //  input.txt   std::ifstream fin("input.txt"); //  output.txt   std::ofstream fout("output.txt"); //       std::vector<int> v; //  ,           std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::inserter(v, v.end())); //   std::sort(v.begin(), v.end()); //  ,          std::copy(v.begin(), v.end(), std::ostream_iterator<int>(fout, " ")); return 0; } 

بضع كلمات عن "السحر" في الكود:

  • واحدة من أسس المكتبة هي التكرارات ، وكذلك الفواصل نصف التي يحددونها. حسب الدلالات (قراءة بالسلوك) فإنها تتزامن مع المؤشرات. أي أن مشغل إلغاء التأجيل * سيعيد إليك العنصر الذي يشير إليه التكرار ، وسيترجم ++ التكرار إلى العنصر التالي. على وجه الخصوص ، يتم تمثيل أي حاوية بتكرارات النهاية [البداية والنهاية) ، حيث تشير نقاط البداية إلى العنصر الأول ، النهاية - لآخر ؛
  • الخوارزميات التي تعمل مع الحاويات ، حيث تأخذ المعلمات بداية ونهاية الحاوية (أو جزء منها) ؛
  • تقوم خوارزمية نسخة النسخ ببساطة بإعادة كتابة العناصر من فترة فاصل إلى أخرى. إذا لم يتم تخصيص أي ذاكرة في الحاوية المستهدفة ، يكون السلوك غير متوقع [ نسخة ] ؛
  • تقوم الدالة inserter بإدراج قيمة في الحاوية قبل التكرار المحدد [ inserter ]
  • يوفر istream_iterator و ostream_iterator وصولًا على نمط الحاوية إلى التدفقات [ istream_iterator ، ostream_iterator ]

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

  1. أعلن بنية البيانات. - يمكنك تحديد شيء مفيد ، ولكن في حالة معينة ، تكون البنية كافية:

     struct man{ std::string firstname, secondname; size_t age; }; 

    أوصي بشدة أن تفكر في تنفيذ مُنشئي النسخ ، باستخدام المعلمات الافتراضية ومشغل النسخ. مع مزيد من التطوير للمشروع ، ستحتاج بالتأكيد لهم.
  2. عوامل تشغيل الإدخال / الإخراج الزائد - يتم التعامل مع هذه العوامل من خلال التكرارات على سلاسل العمليات. على أي حال ، من الشائع استخدامها.

     std::ostream& operator << (std::ostream& out, const man& p){ out << p.firstname << " " << p.secondname << " " << p.age; return out; } std::istream& operator >> (std::istream& in, man& p){ in >> p.firstname >> p.secondname >> p.age; return in; } 
  3. تحديد قواعد ترتيب الكائنات - هذا بالفعل امتداد كبير: يمكنك تخطي عامل التشغيل <، يمكنك وصف تعبير دالة أو عامل أو تعبير lambda. في هذه الحالة ، استخدم الوظيفة.

     bool comparator(const man& p1, const man& p2){ return p1.age < p2.age; } 
  4. تحديد قاعدة لاختيار الكائنات - مرة أخرى ، مجموعة كبيرة إلى حد ما من التطبيقات. هذه المرة ، دعنا نوجد عامل توجيه (كائن من الفئة يتم فيه تعريف عامل التشغيل [ functor ]) والذي يمكنك من خلاله تمرير الفئة العمرية:

     struct predicate{ size_t begin, end; predicate(int p1, int p2): begin(p1), end(p2) {} bool operator ()(const man& p){ return (p.age > begin) && (p.age < end); } }; 

    انتبه إلى مُنشئ المُشغل - وبهذه الطريقة يمكننا تخصيص سلوكه.

حسنًا ، في الواقع ، نقطة الدخول إلى البرنامج:

 int main(){ std::ifstream fin("input.txt"); std::ofstream fout("output.txt"); std::vector<man> v; std::copy(std::istream_iterator<man>(fin), std::istream_iterator<man>(), std::inserter(v, v.end())); std::sort(v.begin(), v.end(), comparator); std::copy_if(v.begin(), v.end(), std::ostream_iterator<man>(std::cout, "\n"), predicate(20, 25)); std::copy(v.begin(), v.end(), std::ostream_iterator<man>(fout, "\n")); return 0; } 

كما ترون ، فإن التغييرات في الوظيفة الرئيسية ضئيلة ، وتؤثر فقط على نوع عناصر المتجه. بالإضافة إلى إضافة مكالمة إلى خوارزمية copy_if. ظهرت هذه الخوارزمية المفيدة مع معيار C ++ 11 ، وهي تنسخ العناصر من حاوية واحدة فقط إلى تلك العناصر التي تفي بالشرط.

ما هي الاستنتاجات التي يمكن استخلاصها من هذا؟

  1. إن معرفة خوارزميات المكتبة القياسية واستخدامها بفعالية يسرع عملية التطوير بشكل كبير (بشكل أدق ، يؤدي إلى التلقائية).
  2. من المفيد الإعلان عن المنشئات المختلفة ومشغلي النسخ لهياكل البيانات. يتم استخدامها في المواقف المختلفة ، خاصة عند إدراج العناصر في حاويات.
  3. للراحة ، يمكنك زيادة التحميل على مشغلي المدخلات والمخرجات ، وكذلك مشغل المقارنة ومشغل الطلب.
  4. Functors - أداة قوية تتيح لك تنفيذ وظائف مع "الذاكرة" أو سلوك إضافي
  5. ... ربما بعض أكثر ...

شكرا لك على التحمل!

كل رمز البرنامج:

an_example.cpp
 #include <string> #include <vector> #include <fstream> #include <algorithm> #include <iostream> #include <iterator> struct man{ std::string firstname, secondname; size_t age; }; std::ostream& operator << (std::ostream& out, const man& p){ out << p.firstname << " " << p.secondname << " " << p.age; return out; } std::istream& operator >> (std::istream& in, man& p){ in >> p.firstname >> p.secondname >> p.age; return in; } bool comparator(const man& p1, const man& p2){ return p1.age < p2.age; } struct predicate{ size_t begin, end; predicate(int p1, int p2): begin(p1), end(p2) {} bool operator ()(const man& p){ return (p.age > begin) && (p.age < end); } }; int main(){ std::ifstream fin("input.txt"); std::ofstream fout("output.txt"); std::vector<man> v; std::vector<man>::iterator i; std::copy(std::istream_iterator<man>(fin), std::istream_iterator<man>(), std::inserter(v, v.end())); std::sort(v.begin(), v.end(), comparator); std::copy_if(v.begin(), v.end(), std::ostream_iterator<man>(std::cout, "\n"), predicate(20, 25)); std::copy(v.begin(), v.end(), std::ostream_iterator<man>(fout, "\n")); return 0; } 

ببليوغرافيا

  1. ستيبانوف آل. لي منغ ، مكتبة النماذج القياسية ، 1995
  2. المرجع CPP ، نسخة
  3. المرجع CPP ، الواضع
  4. مرجع CPP ، istream_iterator
  5. المرجع CPP ، ostream_iterator
  6. ويكي functor

Source: https://habr.com/ru/post/ar433218/


All Articles