b.m.s

الطريق إلى إحتراف التعامل مع STL

30 ردود في هذا الموضوع

مكتبة القوالب المعيارية Standard Template Library

وتختصر بــــ STL وتمثل دعم للغة ++C من توفير عدد من القوالب والخوارزميات الجاهزة اللتي تزيد من إنتاجية اللغة وتساعد على إختصار الوقت في كتابة الأكواد وغير ذلك فالمكتبة تعتبر من أسرع المكتبات وأقواها أداءً وهذه واضح من بُنيتها وأسس علاقاتها الداخلية . وهذه المكتبة مبنية على القوالب "template" أي أنها تدعم أي نوع وهذا ما زادها قوة بالإضافة إلى دعمها مفهوم generic programming و metaprogramming وأيضاً تدعم مبادئ Object oriented programming وهذا مما يزيد في قوتها .

ولكي تفهم تركيبة هذه المكتبة وتحسن التعامل معها يجب أن تعرف أنها تقوم على ثلاثة مفاهيم أساسية وهي :-

الوعاء ( Container ) :- وهي يحتوي على عدد من الكائنات التي لها نفس النوع ويقوم بإدارتها بواسطة الطرق "method" الموجودة به مثل vector , list , stack , set , map , multiset .

الخوارزمية (Algorithm) :- من اسمها هي خوارزميات تقوم بعدد من الوظائف والمهام على الوعاء مثل الحذف أو الإضافة أو البحث مثل copy , search , find , find_if , sort , qsort ,remove .

المكرر (Iterator) :- وهو يستخدم للتنقل بين عناصر الوعاء وهو الوسيط الذي يتم به التخاطب بين الوعاء وبين الخوارزميات فالخوارزميات لا تستقبل Container كوسيط بل تستقبل iterator يؤشر على بداية عناصر الوعاء ونهايته أو يؤشر على مجموعه جزئية منه .

وهذا رسم يوضح العلاقة بين هذه العناصر الثلاثة .

stl1.jpg

ومن الرسم يتضح أن الــ Container تُرسل إلى الـــAlgorithm عن طريق الــ Iterator فالمكرر هو لغة التخاطب بين الوعاء والخوارزمية .

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

Adapter : وهو يقوم بإضافة واجهة جديدة لـــ component موجودة بحيث تستطيع استخدام نفس component لكن بواجهة جديدة تتناسب مع ما حاجتك .

Function Object : وتسمى بإختصار functor وهو كائن لكن يقوم بمهام function العادية إي أنك لن تفرق بينه وبين الدالة العادية لأنه قام بإعادة تعريف للمعامل ( ) فصار مثل الدالة العادية في الاستدعاء وله فوائد كثيرة سنذكرها في حينها إن شاء الله .

Allocator : وهو المسؤول عن إدارة الذاكرة وحجز وإرجاع الذاكرة واستخراج العناوين للكائنات في هذه المكتبة . والحالة الافتراضية له هو أنه يستخدم new و delete العادية لكن ممكن تطويرة ليقوم مقام Garbage Collection في المكتبة .

عموماً هذه تعتبر مقدمة عن STL وعن المفاهيم المتعلقة بها وفي الدرس المقبل سأشرح عن Containers وسنأخذ مثالين عمليين منها وهي vector و string.

ملاحظة الصور مأخوذة من كتاب ومو أنا اللي صنعتها فلا تنسون الحقوق محفوظة لصاحبها . وإذا فيه أي استفسار أنا جاهز .وأيضاً إذا فيه أي ملاحظات فأنا جاهز وترى هذه أول مرة أكتب فيه درس :D

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الله يبارك فيك

و بانتظار الدرس التالي ...

بس أتمنى من الأعضاء ترك هذا الموضوع للدروس و الأسئلة حولها ... و ترك النقاش حول أفضلية هذه المكتبة أو فاعليتها للموضوع الآخر ..

و شكرا مرة أخرى أخي b.m.s

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جميل، استمرّ... ،

ملاحظة: لقد وضعت في الدرس تعريفات كثيرة ومصطلحات متتالية، وهذا يشتت الذهن، لأتمنّى أن تشرح أكثر عن كل شيء:مثلاً : مفهوم generic programming لو وضهت تعريفه بعده..وأهميته...

إن هذه الملاحظة لا تعني أن درسك لم ينل إعجابي بل بالعكس رائع.. وكل ما عدا تلك الملاحظة كان ممتعًا .. خصوصًا : ( أداءً ) <-- بالفعل أفرح عندما أرى كاتب متمكن من لغته وهمزاتها :)

تم تعديل بواسطه إسماعيل ابراهيم
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

هل يجب اتقان template مع الكلاس .. حتى استطيع افهم الدروس .

سؤال اخر :

ماذا نقصد مفهوم generic programming و metaprogramming .

يمكن السؤال برا الموضوع شوي .. لكن نريد نبذة في سطر واحد .. وسنفهم ان شاء الله .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

هلا أخوي aubada وحياك الله وأهم شئ الفايدة لي ولكم ;)

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

مرحبا بأخي الشمري وطبعاً يجب أن تتقن الtemplate مع الـ class و الـtemplate مع function كمفاهيم أساسية وبعدين تأتي المفاهيم اللاحقة بعدها

ونزولاً عند رغبة الأخ إسماعيل والشمري سنتوقف لإستراحة بسيطة عند بعض المصطلحات ومن ثم نعاود المسير ;)

ونبدأ الإستراحة :-

generic programming هو مصطلح يطلق على برمجة تقوم على كتبة خوارزميات و أصناف عامة يمكن إستخدامها مع أغلب الأنواع دون الحاجة إلى إعادة كتابتها مرة أخرى . وفي لغة ++C يتم ذلك عن طريق إستخدام الـtemplate مثال

template<class T>
class ِArray{
public:
T obj;
};

الآن لو قلنا <Object<int فراح يترجم الكود السابق إلى

class Object{
public:
int obj;
};

ونفس الكلام لو عرفنا صنف وسمينها مثلاً Student فنقدر نقول <Object<Student فيتفسر الكود السابق كالتالي

class Object{
public:
Student obj;
};

قد يتسائل البعض ما الفائدة من هذا ؟ أقول وبكل بساطة إفرض إنك تريد تكون صنف (class) ويعمل عمل المصفوفات ويحتوي على طرق تساعده على معالجة وإدارة نفسه مثل class vecotr في STL فإن أسهل الطرق هي أن تجعله من نوع template بحيث يصبح

template<class T>
class Object{
public:
T * obj;
};

وبكذا تستطيع تكون <Array<int أو من أي نوع .

ونفس الكلام ينطبق على الخوارزميات بدل ما تكون عندك خوارزمية تستقبل مصفوفة من أعدد صحيحة وتطبعهم يمكن نخليها مصفوفة عامة من أي نوع وبكذا راح

يوفر علينا وقت كتابة الكود لأننا سنكتب خوارزمية واحدة فقط .

Metaprogramming :- هي برمجة تقوم على كتابة برامج تقوم بنفسها بتوليد وإنتاج أكواد أو بيانات خاصة بها عند ترجمة الملف . طبعا في اللغات ذات interpreter مثل php و غيرها اللي تكون الترجمة فيها وقت التنفيذ تكون هذه البرمجة قوية ويمكن منها تعمل أي شئ يخطر على بالك لكن في لغات ال Compiler تكون البرمجة أضيق قليلاَ إلا أنها محتفظه بقوتها . في لغة ++C يمكن تطبيق هذا المفهوم عن طريق preprocessor أو طريق template الذي يعتبر الأفضل وأقوى . فمثلاً : تأمل هذا الكود

#define MAX(x,y) ((x) > (y) ? (x) : (y))

int hello()
{
int i1 , i2;
cin>>i1;
cin>>i2;
return MAX(i1,i2);
}

هنا سيتحول البرنامج بعد ترجمته إلى

int hello()
{
int i1 , i2;
cin>>i1;
cin>>i2;
return ((x) > (y) ? (x) : (y));
}

أنت الآن كتبت برنامج قام بإنتاج كود بنفسه لكن هذا بإستخدام preprocessor اما بإتخدام الtemplate فإنك تستطيع عمل أكثر من هذا تستطيع عمل if-statement أو while او switch أو حتى Recursive أو حتى bubble Sort و بهذا بيختصر عليك عملية كتابة الكود لكن راح يكون الكود أكبر ومحدود في وقت الترجمة .

وللإستزادة زورا هذا الرابط http://osl.iu.edu/~tveldhui/papers/Templat...s/meta-art.html

واللي يملك إضافة ممكن يضيف ومنها أستفيد ويستفيد الأعضاء

أتمنى أني شرحت هذه المفاهيم والسلام عليكم ورحمة الله وبركاته

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ولله بعد هذا الكلام لا توجد إضافات :) بارك الله فيك يا bms

و لكن يا أخى عندى طلب أرجو ألا تضيق به, أرجو شرح ال functors و ال allocators بالتفصيل.

شكرا و أعانك الله.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ما شاء الله بعد هذا التعب مافيه إلا كم رد

توني عرفت معانات كتَاب الدروس وأولهم الشمري

عموما راح أكمل الدروس بكرة أو بعده

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
ما شاء الله بعد هذا التعب مافيه إلا كم رد

توني عرفت معانات كتَاب الدروس وأولهم الشمري

عموما راح أكمل الدروس بكرة أو بعده

welcome to our world

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
welcome to our world

:D

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

علامك يا رجل !!

وين string و vector و stack .. تراك تورطت معنا كل يوم نسوي up.. وعاد حنا طماعين .. والله اني متحمس جدا لدروسك ... متعاجز من ترجمة دروس الاجانب .الغثيثة ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

وين البقة يا معلم

حفظنا الدرس الأول بصم .... :D

في انتظار الدروس القادمة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
علامك يا رجل !!

وين string و vector و stack .. تراك تورطت معنا كل يوم نسوي up.. وعاد حنا طماعين .. والله اني متحمس جدا لدروسك ... متعاجز من ترجمة دروس الاجانب .الغثيثة ..

وين البقة يا معلم

حفظنا الدرس الأول بصم .... :D

في انتظار الدروس القادمة

هههههههههههههههه أحرجتوني :P حسبتكم نسيتوا :lol:

عموما أنا إنشغلت هذه الأيام وإبشروا باللي يرضيكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

نكمل بعون الله الدروس في المكتبة الرائعة STL : وفي الدرس السابق أخذنا نظرة عامة على المكتبة وعناصرها ومكوناتها والآن سندخل في شرح أول عنصر من عناصر المكتبة بالتفصيل وهو :-

الوعاء ( Container ) :-

عرفناه مسبقاً بـــ " وهو يحتوي على عدد من الكائنات التي لها نفس النوع ويقوم بإدارتها بواسطة الطرق "method" الموجودة به ويوجد عدة أمثلة على الوعاء مثل vector , list , stack , set , map , multiset ." طبعا لو نظرت إلى هذه الأوعية تجد أنها تقسم إلى ثلاث فئات وسندرس بعضاً من خصائصها :-

1) الأوعية المتسلسلة ( Sequence Containers ) :-

وهي الــ Container اللي تكون البيانات المخزنة بها متسلسلة بدون أية علاقة تحكم بينها - يعني أنت اللي تحدد بالضبط وين يخزن العنصر – ولا توجد دالة تكون مسئولة عن ترتيب العناصر . والـ Containers هي vector و list و deque .

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

- vector :- يقوم مقام المصفوفة العادية " التقليدية " في C++ ومما يميزه أنه كتب بطريقة ذكية ليوفر أداء عالي مع الاستخدام الفعال للذاكرة ووجود طرق جاهزة فيه تساعد على إدارته ولو تلاحظ العلاقة بين الحجم الحالي للــــ vector - عن طريق الطريقة size - والسعة الحالية له – عن طريق الطريقة capacity – تدرك معنا هذا الكلام ونأتي إلى الخصائص :-

1) مكان تعريفه :- في الملف الرأسي : vector

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class vector;

3) الوصول إلى العناصر:- يتم الوصول إلى العناصر بشكل مباشر لأي عنصر متواجد فيه يعني نفس خاصية المصفوفات مثل تقدر تقول [v[10 على اعتبار v هو vector.

4) الإضافة والحذف منه:- يتميز بالسرعة في الإضافة الخلفي للبيانات حيث أنه سيكون الخيار الأفضل في ذلك . وتستطيع تطبيق هذه الطريقة باستخدام push_back حيث إنها تحجز خانة جديدة للعنصر إذا لم يوجد مكان في الذاكرة . ولا يوفر طريقة للإضافة من الأمام مثل الــ Containers الأخرى التي توفر push_front وهذا يرجع إلى طريقة كتابة implementation لها وله أيضاً ولكن vector يوفر طريقة تقليدة وهي insert يمكن من خلالها إدخل البيانات من الأمام . وأما الإضافة من المنتصف فهو مصفوفة " يعني يحتاج shift لكن لا تقلق هو من سيقوم بهذا العمل " . وبالنسبة للحذف فهو بالضبط مثل الإضافة.

5) الخيارات المتوفرة :- يوفر خيارات عديدة للمستخدم فمثلاً إذا أردت عند الوصول إلى أي عنصر أن تدقق هل تجاوز المدى أم لا فاستخدم الطرقة at حيث يوجد بها range check أما إذا أردت زيادة السرعة على حساب الآمان فيمكن أن تستخدم العامل [ ] التقليدي فلا يوجد به range check . وأيضا إذا كان vector من نوع Boolean فيوجد له Implementation خاص فيه يوفر الذاكرة مع السرعة في الأداء مع وجود طرق إضافية فيه .

6) أمثلة على استخدامه :-

أولاً:- كيفية تعريفة.

الآن سنعرف vector من نوع int .

vector<int> v1;  //	  لم تحدد حجمه بعد
// OR
// vector<int> v1(15); // الآن حددت عدد العناصر التي سوف يبدأ بها

طيب إفرض كانت عندك مصفوفة حجمها 10 عناصر وأردت نقلها إلى vector هل ستحتاج إلى for-loop لنقلها ؟ الجواب لا . فقط في جمله واحده تستطيع نقلها كيف !!! هذا هو الجواب :-

int a1[]={10,11,12,13,14,15,16,17,18,19}; // هذه المصفوفة التي نريد نقلها 
vector<int> v1(a1 , a1+10); // فقط بجمله واحدة

الذي قمنا به هو أننا أرسلنا عنوان المصفوفة " بداية المصفوفة " ونهايتها . ونفس الكلام ينطبق لو كانت البيانات موجودة في list و أردت أن تنقلها إلى vector أو العكس .

ثانياً :- المرور عليه بالكامل :-

توجد طريقة ذكية وسريعة لكي تمر على جميع العناصر وهي بإستخدام الــ iterator لكن بما أنه سيكون موضوعنا في الدرس القادم فلن أشرحه في هذا الدرس وسأذكر طريقة أخرى وهي عن طريق الدالة size . لنفرض أن الــ vector السابق أردت المرور عليه وطباعة الأعداد اللي أكبر من 15 فسوف يكون الكود كالتالي :-

for( int i=0; i < v1.size(); i++)
if(v1[i] > 15 )
print(v1[i]);

طبعاً توجد دالة في المكتبة إسمها for_each تقوم بهذا الغرض لكن لم يحن الوقت لشرحها فهي تحتاج إلى فهم الـــiterator .

شرح مفصل لدوال الــ vector :-

1) البناء ( Constuctor ) :-

ملاحظة :-

n هوي عدد . c و c1 هما vector . beg و end و pos هما مؤشرات على العناصر .

stl_tab1.jpg

2) الطرق الغير معدِلة :-

stl_tab2.jpg

3) الطرق المعدِلة:-:-

stl_tab3.jpg

- list :- هي عبارة عن قائمة مترابطة مضاعفة (doubly linked list ) توفر دوال كثيرة تساعد في إختصار الوقت في كتابة الأكواد وهي أكثر من الدوال المتوفرة للــ vector ونمر على خصاصئة :-

1) مكان تعريفه :-في الملف الرأسي : list

2) تعريفه في المكتبة :-على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class list;

3)الوصول إلى العناصر:- إذا كنت قد درست linked list في مادة Data Structures فستعرف أن أشد عيوبها أنك لا تستطيع الوصول إلى العنصر مباشرة بل تحتاج إلى التحرك من بداية القائمة حتى العنصر المطلوب عبر جملة تكرر أو أكثر من جملة واحدة لكي تصل إلى العنصر المطلوب لكن توجد دالة تسمى advance في الملف الرأسي algorithm ترسل لها المؤشر "iterator سيأتي شرحه بالتفصيل " مع عدد العناصر اللي تريد أن تتخطاها .

4) الإضافة والحذف منه:- تعتبر أفضل وعاء بشكل عام في الإضافة والحذف من حيث السرعة من أي مكان فهي لا تحتاج إلى shift للعناصر فقط تكوين Node جديدة ومن ثم ربطها ببقية القائمة فقط .

5) الخيارات المتوفرة :-توفر طرق أكثر من المتوفر في الوعاء vector فمثلاً توجد الطريقة merge التي تدمج قائمتين و sort و reverse وكلها يتضح عملها من إسمها .

- deque :- هو إختصار لــ double-ended queue ومن إسمه يتضح أن له نهايتين و يجمع ما بين سرعة وفعالية الــ vector في العمليات وبين سهولة ومرونة الــ list في الإضافة و الحذف ويمكن الإضافة فيه من الأمام أو الخلف . ونمر على الخصائص :-

1) مكان تعريفه :- في الملف الرأسي : deque

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class deque;

3)الوصول إلى العناصر:- يعتبر مثل الــ vector ويدعم جميع ما يدعم ال vectorمن الوصول المباشر والعشوائي للعناصر " لكن في الحقيقة فالوصول يتغرق أكثر من خطوة لكنها لا تذكر " .

4) الإضافة والحذف منه:- يدعم ما يدعمه الــ list و الــ vector حيث يمكن الإضافة من الأمام عن طريق push_front أو الحذف أيضاً عن طريق pop_front ويمكن أيضا الإضافة من الخلف عن طريق push_back او الحذف عن pop_back أما الإضافة من الوسط أو الحذف فإنه يقوم بعملية shift للعناصر نظراً للــ implementation المكتوب فيه " طبعاً الـــ implementation حق معقد جداً "

5) الخيارات المتوفرة :- لا يوفر خيارات إضافة أكثر من أنه يمثل حل وسط ما بين الــ list و vector في الإستخدام حيث يوفر ما عجز عنه الــ vector وهي الإضافة من الأمام ويوفر الوصول العشوائي والمباشر للعناصر الذي عجزت عنه الــ list .

2) الأوعية الترابطية ( Associative Containers ) :-

وهي الأوعية اللي تكون بياناتها مرتبة على أساس المفتاح للكائن وقد يكون المفتاح هو نفسه قيمة الكائن مثل ما هو موجود في set و multiset أو يكون منفصل عن القيمة مثل ما هو موجود في map و multimap. و ولكن الترتيب الإفتراضي فيها هو تصاعدي حيث تتولى ترتيب العناصر الـدالة less الموجودة في الملف الملف الرأسي functional ويمكنك تغيرها وإستخدام بدل منها greater أو greater_equal أو تكتب الدالة الخاصة بك بس ملاحظة هذه لو أكون دقيق ليست دالة هي functor "

راجع الدرس السابق " والآن سنأخذ نبذه سريعة عنهما :-

- set & multiset :- هي عبارة عن وعاء مرتبة عناصره على حسب القيمة من الأصغر إلى الأكبر " هذا الترتيب الافتراضي " و implementation الداخلي هو عبارة عن red black tree ويعتبر مفيد لمن يبحث عن وعاء يقوم بترتيب عناصره بشكل تلقائي . وللمعلومية الفرق الوحيد في set و multiset هو أن set لا تقبل تكرار العناصر فيها أما الـــ multiset فهي ترحب بالعناصر المتكررة . وهذه خصائصه

1) مكان تعريفه :- في الملف الرأسي : set

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Compare = less<Type>,
class Allocator = allocator<Type> >
class set;

template <class T,
class Compare = less<Type>,
class Allocator = allocator<Type> >
class multiset;

3)الوصول إلى العناصر:- توفر ما وفرته الـــlist فقط من الوصول الغير مباشر إلى العناصر .

4) الإضافة والحذف منه:- تعطي مرونة عالية في الإضافة فهي عبارة عن tree لكن في الحذف قد يستغرق وقت أطول .

5) الخيارات المتوفرة :- توفر خيارات عديدة منها مثلاً إمكانية كتابتك دالة المقارنة الخاصة فيك ولا تحتاج إلى استخدام الدالة الافتراضية less. ترك للمبرمج حرية الاختيار إما بدعم التكرار أو بمنعه.

6) أمثلة على استخدامه:-

أولاً:- كيفية تعريفة.

الآن سنعرف set من نوع int .

set<int> s1;  //	وأيضاً ترتيبه من الأصغر إلى الأكبر  لم تحدد حجمه بعد
// OR
// set<int> s1(15); // الآن حددت عدد العناصر التي سوف يبدأ بها

ماذا الآن لو أردت أن أجعل ترتيب العناصر من الآكبر إلى الأصغر فالحل سهل وهو أستخدم الــgreater functor وهذا الكود يوضح الفكرة :-

set<int , greater<int> > s1;

- map & multimap :- هي عبارة عن وعاء مرتبة عناصره على حسب المفتاح من الأصغر إلى الأكبر " هذا الترتيب الافتراضي " فكل عنصر تضيفه إلى المجموعة يجب أن يحتوي على key و value أي مفتاح

وقيمة . و بالنسبة للخصائص التالية :-

1) مكان تعريفه :- في الملف الرأسي : map

2) تعريفه في المكتبة :- على هذا النحو

	   template <class Key, class T,
class Compare = less<Key>,
class Allocator = allocator<pair<const Key,Type> > >
class map;

template <class Key, class T,
class Compare = less<Key>,
class Allocator = allocator<pair<const Key,Type> > >
class multimap;

3)الوصول إلى العناصر:- نفس ما قلنا عن الــ set .

4) الإضافة والحذف منه:- نفس ما قلنا عن الــ set .

5) الخيارات المتوفرة :- تعطي خيارات عديدة أفضلها إمكانية البحث عن العنصر عبر مفتاحه بطريقه سهله وبسيطة عن طريق العامل [ ] فمثل إذا كان المفتاح من نوع string وكانت m من نوع map وأردت البحث عن مفتاح "ali" فما عليك إلا كتابة ["m["ali فقط وهذه تذكرني بالمصفوفة المترابطة الموجودة في php ولغات السكربت .

6) أمثلة على استخدامه:-

أولاً:- كيفية تعريفة.

الآن سنعرف map مفاتيحه من نوع int وقيمة من نوع string.

map<int,string> s1;  //	وأيضاً ترتيبه من الأصغر إلى الأكبر  لم تحدد حجمه بعد

ماذا الآن لو أردت أن أجعل ترتيب العناصر من الآكبر إلى الأصغر فالحل سهل وهو أستخدم الــgreater functor وهذا الكود يوضح الفكرة :-

map<int,string , greater<int> > s1;

لاحظ إن الــ greater يطلب وسيط بنفس نوع الــ key وليس الــ value

ملاحظة :- تسمى الـــ Associative Containers و Sequence Containers بــــــــ first-class Containers " الأوعية الأولية " وهذا لأنها تدعم الــــ Iterator من جهة ومن جهة أخرى فهي تعتبر framework لمكتبة STL .

3) Container Adapters " لم أعرف ترجمتها إلى كلمة مستساغة " :-

وهي الأوعية التي تقوم بأداء مهم معينة ولها شروط وقيود لاستخدامها وهي في الأساس تعتبر تغليف لأحد الــ Sequence Containers و الوعاء الافتراضي هو deque لهم كلهم إلا واحد منهم يستخدم vector وهذه الأوعية هي stack و queue و priority_queue . طبعاَ جميعها لا توفر وصول مباشر ولا غير مباشر أو عشوائي عن طريق الـــIterator لأنها ببساطة لا تدعمه ولا يمكنك الوصول إلى العناصر إلا عن طريق الدوال المتوفرة لذلك سأشرح كل دالة باختصار ونبدأ على بركة الله :-

- stack :- هو وعاء يطبق قاعدة الذي يدخل أخيراً يخرج أولاً ( LIFO ( Last In First Out وخصائصه هي كالتالي :-

1) مكان تعريفه :- في الملف الرأسي stack

2) تعريفه في المكتبة :- على هذا النحو :-

									   template <class Type,
class Container = deque<Type> >
class stack;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى stack

pop : وهذه يحذف آخر عنصر تمت إضافته إلى stack

top : وهذه يعيد آخر عنصر تمت إضافته إلى stack دون حذفه .

- queue:- هو وعاء يطبق قاعدة الذي يدخل أولاً يخرج أولاً ( FIFO ( First In First Out وخصائصه هي كالتالي:-

1) مكان تعريفه :- في الملف الرأسي queue

2) تعريفه في المكتبة :-

							   template <class T,
class Container = deque<Type> >
class queue;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى queue

pop : وهذه يحذف أول عنصر تمت إضافته إلى queue

front : وهذه يعيد أول عنصر تمت إضافته إلى queue دون حذفه .

back : وهذه يعيد أخر عنصر تمت إضافته إلى queue دون حذفه.

- priority_queue:- هو وعاء يطبق قاعدة أن العنصر الأعلى أولوية هو من سيكون في الأمام وخصائصه هي كالتالي:-

1) مكان تعريفه :- في الملف الرأسي queue

2) تعريفه في المكتبة :-

	   template <class T,
class Container = vector<Type>,
class Compare = less<typename Container::value_type> >
class priority_queue;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى priority_queue

pop : وهذه يحذف أعلى عنصر أولوية تمت إضافته إلى priority_queue

top : وهذه يعيد أعلى عنصر أولوية تمت إضافته إلى priority_queue دون حذفه .

وعموما stack و queue وpriority_queue كلهم يشتركون في دالتين هما size و empty وهي معروفه ولا تحتاج إلى شرح .

وأخيراً : توجد في المكتبة شبة أوعية " near-Containers " وهي string و bitset و valarray لكن ربما سأشرح فقط string لكن ليس الآن . وما يحتاج أعيد كلامي أي إستفسارات أو ملاحظات أو حتى تعديل غلطات نسقبل كل حاقة :lol: وإلى اللقاء في الدرس القادم عن الــ iterator

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أعجبني شرحك ..و هو مميز للغاية ..

انا فقط ركزت على الvector .

وعندي أسئلة وملاحظات .:

أولا :

حاولت أني استخدم insert ولكن يظهر لي خطأ ولا اعرف ماهو السبب . .

	vector<int> v1(10); 

v1.insert(5,130);
cout<<v1[5]<<endl;

يقول انه لازم البارمتر الاول يكون int * ؟؟

أريد مثال على طريقة استخدام

insert();

وهل معنى وفائدة الدالةinsert انها تقوم بادخال قيم داخل الvector وباي مكان

يعني تدخل قيم في اول الvector او في اخره او حتى في منتصف الvector

السؤال الثاني :

وهو شبيه باالسؤال الاول

كيف استخدم

erase

حيث انه يطلب مني

int *

يعني عنوان لشيء ما ..

ولا اعرف كيف استخدمه .

وهنا عندي استفسار .

انا فهمت من كلامك

انه الvector لايملك مرونة كبيرة ..

حيث لايمكن اضافة عناصر او حذفها الا من اخر الvector ..

لكن الدالتين

insert و erase أليست تقوم بحذف واضافة عنصر للvector من وفي اي مكان

------

بقي سؤال اخير ...

مالذي تقصده بالطرق المعدلة والطرق غير المعدلة عندما شرحت الvector's method

------

وايضا اتمنى لو يكون لبقية الاوعية نصيب من الشرح كما حدث مع الvector

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
أعجبني شرحك ..و هو مميز للغاية ..

هذه شهادة أعتز بها

حاولت أني استخدم insert ولكن يظهر لي خطأ ولا اعرف ماهو السبب . .

	vector<int> v1(10); 

v1.insert(5,130);
cout<<v1[5]<<endl;

يقول انه لازم البارمتر الاول يكون int * ؟؟

أخوي أنا ذكرت prototype حق دالة insert

v.insert(pos,elemnt);

وقلت

beg و end و pos هما مؤشرات على العناصر .

يعني pos هو pointer وليس index أو بالمعنى الأصح هو iterator ولو تبي تجعل الكود صحيح يكون التعديل بإضافة الدالة begin

vector<int> v1(10); 

v1.insert(v1.begin() + 5,130);
cout<<v1[5]<<endl;

لاحظ إن الدالة هذه ما شرحتها لأني ما أبي أحرق الـــ iterator لكن يمكنك إعتبار هذه الدالة ترجع مؤشر على بداية المصفوفة ومن بداية المصفوفة تقدر تتنقل بين العناصر يعني إذا زدت 5 رحت للعنصر الخامس وهكذا لكن تذكر إن هذه الطريقة لا تصلح إلا من Random Access Iterator أي فقط على vector و deque .

أريد مثال على طريقة استخدام

insert();

وهل معنى وفائدة الدالةinsert انها تقوم بادخال قيم داخل الvector وباي مكان

يعني تدخل قيم في اول الvector او في اخره او حتى في منتصف الvector

نعم مثل ماقلت و هذا مثال يوضح .

vector<int> v1;

v1.insert(v1.begin() , 1 ); // تدخل قيمة من البداية
v1.insert(v1.end() , 3 ); ظظ تدخل قيمة من النهاية
v1.insert(v1.begin()+1,2); تدخل قيمة على حسب الرقم اللي بعد الإضافة

السؤال الثاني :

وهو شبيه باالسؤال الاول

كيف استخدم

erase

حيث انه يطلب مني

int *

يعني عنوان لشيء ما ..

ولا اعرف كيف استخدمه .

مثل ما قلت الدالة erase تطلب iterator وتقدر تحصل علىه من خلال الدوال begin و end يمكن تقول

v1.erase(v1.begin());

أو

v1.erase(v1.begin() + number);

لكن إياك أن تكتب

v1.erase(v1.end());

لماذا !!!!!!!!!!!!!!! :wacko: السبب طويل ولا أود شرحهه الآن ولهذا السبب أجلت ذكر هاتين الدالتين كلياً ;)

وهنا عندي استفسار .

انا فهمت من كلامك

انه الvector لايملك مرونة كبيرة ..

حيث لايمكن اضافة عناصر او حذفها الا من اخر الvector ..

لكن الدالتين

insert و erase أليست تقوم بحذف واضافة عنصر للvector من وفي اي مكان

الــ vector يملك فقط push_back و pop_back لكن توجد أوعية تملك push_front و pop_front بالإضافة إلى ما يمكله الــ vector مثل list نعم كلهم يملكون الدالتين insert و erase لكن قد تكلف الكثير لأن الإضافة من الأمام بالنسبة للــ vector تكلف كثيراً . فهم في interface قللوا هذه الميزة لكن لم يلغوها وأجبروك إنك إذا كنت تبي تضيف من الأمام تستخدم غير الـــ vector .

بقي سؤال اخير ...

مالذي تقصده بالطرق المعدلة والطرق غير المعدلة عندما شرحت الvector's method

------

:lol: سؤال محرج :unsure: لا بس حبيت أصنفها فما لقيت غير هذا التقسيم وأقصد بالمعدلة اللي تعدل في نفس الــ vector يعني تغير فيه شئ .

وايضا اتمنى لو يكون لبقية الاوعية نصيب من الشرح كما حدث مع الvector

وش بقى ما شرحته الــ vector فصلَت فيه و الــ deque نفس مميزات الـــ vector بالإضافة إلى push_front و pop_front و الــ list نفس مميزات الــ deque لكن بدون at والعامل [ ] .

stack و queue و priority_queue كلها لا توجد دوال غير اللي شرحتها .

بقي الــ set و map تعتبر معقدة وصعبة قليلاً ولا أتوقع إن أحد بيستخدمها .

والسلام عليكم ورحمة الله وبركاته

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
بقي الــ set و map تعتبر معقدة وصعبة قليلاً ولا أتوقع إن أحد بيستخدمها .

:o إزاى يا أخى أنا أعتبر ال map من أهم الأوعية الموجودة فى ال STL و أنا عن نفسى أستخدمها كثيرا جداااا.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
:o إزاى يا أخى أنا أعتبر ال map من أهم الأوعية الموجودة فى ال STL و أنا عن نفسى أستخدمها كثيرا جداااا.

والله أخوي 'Blueteeth' أنا أتمنى إني أشوف مبرمجين عرب يستخدمون STL

لأن مشكلة هذه المكتبة مهجورة

لكن قاعدين يطورون فيها دائماً وأغلب المبرمجين ما إستفادوا منها

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
والله أخوي 'Blueteeth' أنا أتمنى إني أشوف مبرمجين عرب يستخدمون STL

لأن مشكلة هذه المكتبة مهجورة

لكن قاعدين يطورون فيها دائماً وأغلب المبرمجين ما إستفادوا منها

انا استخدمتها مرة .. كبديل عن hash table لأنه اعتقد هذا هو الهدف اللذي صممت من اجله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
انا استخدمتها مرة .. كبديل عن hash table لأنه اعتقد هذا هو الهدف اللذي صممت من اجله

اها :o يعني الSTL في مبرمجين يستخدمونها

خلاص راح أشرح map بالتفصيل :wacko: لكن بعد أن أشرح الـــ iterator

ولكن اخوي حسن ممكن تغير عنوان الموضوع يعني تزيل جملة ", الدرس الأول "

وكمان أنا عندي صور توضح تركيب كل من Vector و map وكل الأوعية

ومجهزه لكن المشلكة إني نسيت أحطها :) فهل عندك حل ؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

يوجد مكتبة رائعة يقدمها مجتمع المصادر المفتوحـة وهي أشمل من الـ STL اسمها BOOST إذا أردتم أن أشرحها فلكم ذلك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

توجد مكتبة لل++C تعمل على جميع الأنظمة وهي سهلة وبسيطة وعملية أيضاً

وتقريباً واجهاتها وتركيبها تشبه واجهات NET. لكن ينقصها الفيجول

وهذا رابط موقعها الرسمي http://appinf.com/poco/info/index.html

وهذا رابطه على موقع sourceforge

http://sourceforge.net/forum/forum.php?forum_id=590413

وللمعلومية أنا أستعملها كثيراً

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الدرس الأول مرفق على شكل ملف pdf حتى يسهل قرائته offline

و إن شاء الله الدرس الثاني مباشرة بعد إكماله و وضع الصور الناقصة

STL_1st_Lesson.pdf

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

نكمل بعون الله الدروس في المكتبة الرائعة STL : وفي الدرس السابق أخذنا نظرة عامة على المكتبة وعناصرها ومكوناتها والآن سندخل في شرح أول عنصر من عناصر المكتبة بالتفصيل وهو :-

الوعاء ( Container ) :-

http://bms676.jeeran.com/stl2.jpg

عرفناه مسبقاً بـــ " وهو يحتوي على عدد من الكائنات التي لها نفس النوع ويقوم بإدارتها بواسطة الطرق "method" الموجودة به ويوجد عدة أمثلة على الوعاء مثل vector , list , stack , set , map , multiset ." طبعا لو نظرت إلى هذه الأوعية تجد أنها تقسم إلى ثلاث فئات وسندرس بعضاً من خصائصها :-

1) الأوعية المتسلسلة ( Sequence Containers ) :-

وهي الــ Container اللي تكون البيانات المخزنة بها متسلسلة بدون أية علاقة تحكم بينها - يعني أنت اللي تحدد بالضبط وين يخزن العنصر – ولا توجد دالة تكون مسئولة عن ترتيب العناصر . والـ Containers هي vector و list و deque .

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

- vector :-

stl4.jpg

يقوم مقام المصفوفة العادية " التقليدية " في C++ ومما يميزه أنه كتب بطريقة ذكية ليوفر أداء عالي مع الاستخدام الفعال للذاكرة ووجود طرق جاهزة فيه تساعد على إدارته ولو تلاحظ العلاقة بين الحجم الحالي للــــ vector - عن طريق الطريقة size - والسعة الحالية له – عن طريق الطريقة capacity – تدرك معنا هذا الكلام ونأتي إلى الخصائص :-

1) مكان تعريفه :- في الملف الرأسي : vector

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class vector;

3) الوصول إلى العناصر:- يتم الوصول إلى العناصر بشكل مباشر لأي عنصر متواجد فيه يعني نفس خاصية المصفوفات مثل تقدر تقول [v[10 على اعتبار v هو vector.

4) الإضافة والحذف منه:- يتميز بالسرعة في الإضافة الخلفي للبيانات حيث أنه سيكون الخيار الأفضل في ذلك . وتستطيع تطبيق هذه الطريقة باستخدام push_back حيث إنها تحجز خانة جديدة للعنصر إذا لم يوجد مكان في الذاكرة . ولا يوفر طريقة للإضافة من الأمام مثل الــ Containers الأخرى التي توفر push_front وهذا يرجع إلى طريقة كتابة implementation لها وله أيضاً ولكن vector يوفر طريقة تقليدة وهي insert يمكن من خلالها إدخل البيانات من الأمام . وأما الإضافة من المنتصف فهو مصفوفة " يعني يحتاج shift لكن لا تقلق هو من سيقوم بهذا العمل " . وبالنسبة للحذف فهو بالضبط مثل الإضافة.

5) الخيارات المتوفرة :- يوفر خيارات عديدة للمستخدم فمثلاً إذا أردت عند الوصول إلى أي عنصر أن تدقق هل تجاوز المدى أم لا فاستخدم الطرقة at حيث يوجد بها range check أما إذا أردت زيادة السرعة على حساب الآمان فيمكن أن تستخدم العامل [ ] التقليدي فلا يوجد به range check . وأيضا إذا كان vector من نوع Boolean فيوجد له Implementation خاص فيه يوفر الذاكرة مع السرعة في الأداء مع وجود طرق إضافية فيه .

6) أمثلة على استخدامه :-

أولاً:- كيفية تعريفة.

الآن سنعرف vector من نوع int .

vector<int> v1;  //	  لم تحدد حجمه بعد
// OR
// vector<int> v1(15); // الآن حددت عدد العناصر التي سوف يبدأ بها

طيب إفرض كانت عندك مصفوفة حجمها 10 عناصر وأردت نقلها إلى vector هل ستحتاج إلى for-loop لنقلها ؟ الجواب لا . فقط في جمله واحده تستطيع نقلها كيف !!! هذا هو الجواب :-

int a1[]={10,11,12,13,14,15,16,17,18,19}; // هذه المصفوفة التي نريد نقلها 
vector<int> v1(a1 , a1+10); // فقط بجمله واحدة

الذي قمنا به هو أننا أرسلنا عنوان المصفوفة " بداية المصفوفة " ونهايتها . ونفس الكلام ينطبق لو كانت البيانات موجودة في list و أردت أن تنقلها إلى vector أو العكس .

ثانياً :- المرور عليه بالكامل :-

توجد طريقة ذكية وسريعة لكي تمر على جميع العناصر وهي بإستخدام الــ iterator لكن بما أنه سيكون موضوعنا في الدرس القادم فلن أشرحه في هذا الدرس وسأذكر طريقة أخرى وهي عن طريق الدالة size . لنفرض أن الــ vector السابق أردت المرور عليه وطباعة الأعداد اللي أكبر من 15 فسوف يكون الكود كالتالي :-

for( int i=0; i < v1.size(); i++)
if(v1[i] > 15 )
print(v1[i]);

طبعاً توجد دالة في المكتبة إسمها for_each تقوم بهذا الغرض لكن لم يحن الوقت لشرحها فهي تحتاج إلى فهم الـــiterator .

شرح مفصل لدوال الــ vector :-

1) البناء ( Constuctor ) :-

ملاحظة :-

n هوي عدد . c و c1 هما vector . beg و end و pos هما مؤشرات على العناصر .

stl_tab1.jpg

2) الطرق الغير معدِلة :-

stl_tab2.jpg

3) الطرق المعدِلة:-:-

stl_tab3.jpg

- list :-

stl6.jpg

هي عبارة عن قائمة مترابطة مضاعفة (doubly linked list ) توفر دوال كثيرة تساعد في إختصار الوقت في كتابة الأكواد وهي أكثر من الدوال المتوفرة للــ vector ونمر على خصاصئة :-

1) مكان تعريفه :-في الملف الرأسي : list

2) تعريفه في المكتبة :-على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class list;

3)الوصول إلى العناصر:- إذا كنت قد درست linked list في مادة Data Structures فستعرف أن أشد عيوبها أنك لا تستطيع الوصول إلى العنصر مباشرة بل تحتاج إلى التحرك من بداية القائمة حتى العنصر المطلوب عبر جملة تكرر أو أكثر من جملة واحدة لكي تصل إلى العنصر المطلوب لكن توجد دالة تسمى advance في الملف الرأسي algorithm ترسل لها المؤشر "iterator سيأتي شرحه بالتفصيل " مع عدد العناصر اللي تريد أن تتخطاها .

4) الإضافة والحذف منه:- تعتبر أفضل وعاء بشكل عام في الإضافة والحذف من حيث السرعة من أي مكان فهي لا تحتاج إلى shift للعناصر فقط تكوين Node جديدة ومن ثم ربطها ببقية القائمة فقط .

5) الخيارات المتوفرة :-توفر طرق أكثر من المتوفر في الوعاء vector فمثلاً توجد الطريقة merge التي تدمج قائمتين و sort و reverse وكلها يتضح عملها من إسمها .

- deque :-

stl5.jpg

هو إختصار لــ double-ended queue ومن إسمه يتضح أن له نهايتين و يجمع ما بين سرعة وفعالية الــ vector في العمليات وبين سهولة ومرونة الــ list في الإضافة و الحذف ويمكن الإضافة فيه من الأمام أو الخلف . ونمر على الخصائص :-

1) مكان تعريفه :- في الملف الرأسي : deque

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Allocator = allocator<Type> >
class deque;

3)الوصول إلى العناصر:- يعتبر مثل الــ vector ويدعم جميع ما يدعم ال vectorمن الوصول المباشر والعشوائي للعناصر " لكن في الحقيقة فالوصول يتغرق أكثر من خطوة لكنها لا تذكر " .

4) الإضافة والحذف منه:- يدعم ما يدعمه الــ list و الــ vector حيث يمكن الإضافة من الأمام عن طريق push_front أو الحذف أيضاً عن طريق pop_front ويمكن أيضا الإضافة من الخلف عن طريق push_back او الحذف عن pop_back أما الإضافة من الوسط أو الحذف فإنه يقوم بعملية shift للعناصر نظراً للــ implementation المكتوب فيه " طبعاً الـــ implementation حق معقد جداً "

5) الخيارات المتوفرة :- لا يوفر خيارات إضافة أكثر من أنه يمثل حل وسط ما بين الــ list و vector في الإستخدام حيث يوفر ما عجز عنه الــ vector وهي الإضافة من الأمام ويوفر الوصول العشوائي والمباشر للعناصر الذي عجزت عنه الــ list .

2) الأوعية الترابطية ( Associative Containers ) :-

وهي الأوعية اللي تكون بياناتها مرتبة على أساس المفتاح للكائن وقد يكون المفتاح هو نفسه قيمة الكائن مثل ما هو موجود في set و multiset أو يكون منفصل عن القيمة مثل ما هو موجود في map و multimap. و ولكن الترتيب الإفتراضي فيها هو تصاعدي حيث تتولى ترتيب العناصر الـدالة less الموجودة في الملف الملف الرأسي functional ويمكنك تغيرها وإستخدام بدل منها greater أو greater_equal أو تكتب الدالة الخاصة بك بس ملاحظة هذه لو أكون دقيق ليست دالة هي functor "

راجع الدرس السابق " والآن سنأخذ نبذه سريعة عنهما :-

- set & multiset :-

stl7.jpg

هي عبارة عن وعاء مرتبة عناصره على حسب القيمة من الأصغر إلى الأكبر " هذا الترتيب الافتراضي " و implementation الداخلي هو عبارة عن red black tree ويعتبر مفيد لمن يبحث عن وعاء يقوم بترتيب عناصره بشكل تلقائي . وللمعلومية الفرق الوحيد في set و multiset هو أن set لا تقبل تكرار العناصر فيها أما الـــ multiset فهي ترحب بالعناصر المتكررة . وهذه خصائصه

1) مكان تعريفه :- في الملف الرأسي : set

2) تعريفه في المكتبة :- على هذا النحو

	   template <class T,
class Compare = less<Type>,
class Allocator = allocator<Type> >
class set;

template <class T,
class Compare = less<Type>,
class Allocator = allocator<Type> >
class multiset;

3)الوصول إلى العناصر:- توفر ما وفرته الـــlist فقط من الوصول الغير مباشر إلى العناصر .

4) الإضافة والحذف منه:- تعطي مرونة عالية في الإضافة فهي عبارة عن tree لكن في الحذف قد يستغرق وقت أطول .

5) الخيارات المتوفرة :- توفر خيارات عديدة منها مثلاً إمكانية كتابتك دالة المقارنة الخاصة فيك ولا تحتاج إلى استخدام الدالة الافتراضية less. ترك للمبرمج حرية الاختيار إما بدعم التكرار أو بمنعه.

6) أمثلة على استخدامه:-

أولاً:- كيفية تعريفة.

الآن سنعرف set من نوع int .

set<int> s1;  //	وأيضاً ترتيبه من الأصغر إلى الأكبر  لم تحدد حجمه بعد
// OR
// set<int> s1(15); // الآن حددت عدد العناصر التي سوف يبدأ بها

ماذا الآن لو أردت أن أجعل ترتيب العناصر من الآكبر إلى الأصغر فالحل سهل وهو أستخدم الــgreater functor وهذا الكود يوضح الفكرة :-

set<int , greater<int> > s1;

- map & multimap :-

stl8.jpg

هي عبارة عن وعاء مرتبة عناصره على حسب المفتاح من الأصغر إلى الأكبر " هذا الترتيب الافتراضي " فكل عنصر تضيفه إلى المجموعة يجب أن يحتوي على key و value أي مفتاح وقيمة وأيضاً الفرق بينهما أن multimap يقبل تكرار المفاتيح أما amp فلا يقب تكرارها . و بالنسبة للخصائص التالية :-

1) مكان تعريفه :- في الملف الرأسي : map

2) تعريفه في المكتبة :- على هذا النحو

	   template <class Key, class T,
class Compare = less<Key>,
class Allocator = allocator<pair<const Key,Type> > >
class map;

template <class Key, class T,
class Compare = less<Key>,
class Allocator = allocator<pair<const Key,Type> > >
class multimap;

3)الوصول إلى العناصر:- نفس ما قلنا عن الــ set .

4) الإضافة والحذف منه:- نفس ما قلنا عن الــ set .

5) الخيارات المتوفرة :- تعطي خيارات عديدة أفضلها إمكانية البحث عن العنصر عبر مفتاحه بطريقه سهله وبسيطة عن طريق العامل [ ] فمثل إذا كان المفتاح من نوع string وكانت m من نوع map وأردت البحث عن مفتاح "ali" فما عليك إلا كتابة ["m["ali فقط وهذه تذكرني بالمصفوفة المترابطة الموجودة في php ولغات السكربت .

6) أمثلة على استخدامه:-

أولاً:- كيفية تعريفة.

الآن سنعرف map مفاتيحه من نوع int وقيمة من نوع string.

map<int,string> s1;  //	وأيضاً ترتيبه من الأصغر إلى الأكبر  لم تحدد حجمه بعد

ماذا الآن لو أردت أن أجعل ترتيب العناصر من الآكبر إلى الأصغر فالحل سهل وهو أستخدم الــgreater functor وهذا الكود يوضح الفكرة :-

map<int,string , greater<int> > s1;

لاحظ إن الــ greater يطلب وسيط بنفس نوع الــ key وليس الــ value

ملاحظة :- تسمى الـــ Associative Containers و Sequence Containers بــــــــ first-class Containers " الأوعية الأولية " وهذا لأنها تدعم الــــ Iterator من جهة ومن جهة أخرى فهي تعتبر framework لمكتبة STL .

3) Container Adapters " لم أعرف ترجمتها إلى كلمة مستساغة " :-

وهي الأوعية التي تقوم بأداء مهم معينة ولها شروط وقيود لاستخدامها وهي في الأساس تعتبر تغليف لأحد الــ Sequence Containers و الوعاء الافتراضي هو deque لهم كلهم إلا واحد منهم يستخدم vector وهذه الأوعية هي stack و queue و priority_queue . طبعاَ جميعها لا توفر وصول مباشر ولا غير مباشر أو عشوائي عن طريق الـــIterator لأنها ببساطة لا تدعمه ولا يمكنك الوصول إلى العناصر إلا عن طريق الدوال المتوفرة لذلك سأشرح كل دالة باختصار ونبدأ على بركة الله :-

- stack :-

http://bms676.jeeran.com/stl9.jpg

هو وعاء يطبق قاعدة الذي يدخل أخيراً يخرج أولاً ( LIFO ( Last In First Out وخصائصه هي كالتالي :-

1) مكان تعريفه :- في الملف الرأسي stack

2) تعريفه في المكتبة :- على هذا النحو :-

									   template <class Type,
class Container = deque<Type> >
class stack;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى stack

pop : وهذه يحذف آخر عنصر تمت إضافته إلى stack

top : وهذه يعيد آخر عنصر تمت إضافته إلى stack دون حذفه .

- queue:-

http://bms676.jeeran.com/stl11.jpg

هو وعاء يطبق قاعدة الذي يدخل أولاً يخرج أولاً ( FIFO ( First In First Out وخصائصه هي كالتالي:-

1) مكان تعريفه :- في الملف الرأسي queue

2) تعريفه في المكتبة :-

							   template <class T,
class Container = deque<Type> >
class queue;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى queue

pop : وهذه يحذف أول عنصر تمت إضافته إلى queue

front : وهذه يعيد أول عنصر تمت إضافته إلى queue دون حذفه .

back : وهذه يعيد أخر عنصر تمت إضافته إلى queue دون حذفه.

- priority_queue:-

http://bms676.jeeran.com/stl10.jpg

هو وعاء يطبق قاعدة أن العنصر الأعلى أولوية هو من سيكون في الأمام وخصائصه هي كالتالي:-

1) مكان تعريفه :- في الملف الرأسي queue

2) تعريفه في المكتبة :-

	   template <class T,
class Container = vector<Type>,
class Compare = less<typename Container::value_type> >
class priority_queue;

3) الطرق التي يدعمها:-

push : وهذه تستقبل العنصر وتضيفه إلى priority_queue

pop : وهذه يحذف أعلى عنصر أولوية تمت إضافته إلى priority_queue

top : وهذه يعيد أعلى عنصر أولوية تمت إضافته إلى priority_queue دون حذفه .

وعموما stack و queue وpriority_queue كلهم يشتركون في دالتين هما size و empty وهي معروفه ولا تحتاج إلى شرح .

وأخيراً : توجد في المكتبة شبة أوعية " near-Containers " وهي string و bitset و valarray لكن ربما سأشرح فقط string لكن ليس الآن .

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ألن تكمل ما بدأت ....

أرجو إكمال ما تحتويه STL ، حتى يكون هذا الموضوع مرجع مفيد لمن يريد

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
ألن تكمل ما بدأت ....

أرجو إكمال ما تحتويه STL ، حتى يكون هذا الموضوع مرجع مفيد لمن يريد

والله العالم إني حاس إني أشرح لنفسي -_-

لا أسأله لا ردود فليه العجله طالما الموضوع في أي وقت راح ألقاه :D ولا أظنه مرجعاً

أظنه مودنتي الشخصية :D

تم تعديل بواسطه b.m.s
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .