include - קרן כליף

++C -‫תכנות מכוון עצמים ו‬
12 ‫יחידה‬
STL – Standard Templates Library
‫קרן כליף‬
‫ביחידה זו נלמד‪:‬‬
‫‪ ‬סקירת ה‪STL -‬‬
‫‪ ‬סוגים של ‪'conatiner‬ים‬
‫‪ ‬איטרטור‬
‫‪Object Functions ‬‬
‫‪ ‬אלגוריתמים‬
‫‪ ‬המחלקה ‪string‬‬
‫‪2‬‬
‫‪© Keren Kalif‬‬
‫‪STL – Standard Template Library‬‬
‫‪ ‬ה‪ STL -‬הוא אוסף מימושים למבני‪-‬נתונים ואלגוריתמים בשפת‬
‫‪++C‬‬
‫‪ ‬מימושים אלו מתבססים על ‪templates‬‬
‫‪ ‬בין מבני‪-‬הנתונים הממומשים ניתן למצוא‪:‬‬
‫‪ ‬מערך‬
‫‪ ‬רשימה מקושרת‬
‫‪ ‬מפה‬
‫‪ ‬קבוצה‬
‫‪ ‬בין האלגוריתמים הממומשים ניתן למצוא‪:‬‬
‫‪ ‬חיפוש‬
‫‪ ‬מיון‬
‫‪ ‬מינימום ומקסימום‬
‫‪3‬‬
‫‪© Keren Kalif‬‬
‫‪ - STL‬יתרונות‬
‫‪ ‬שימוש בקוד מוכן לפעולות שכיחות‬
‫‪ ‬ניהול זכרון‬
‫‪ ‬מימושי האוספים השונים בעלי ממשק כמעט זהה‬
‫‪ ‬מקל על למידתם‬
‫‪ ‬מקל על החלפת שימוש אחד באחר‬
‫‪ ‬בקישור הבא נתן למצוא את כל מה שה‪ STL -‬מכיל‬
‫‪http://www.sgi.com/tech/stl/table_of_contents.html‬‬
‫‪4‬‬
‫‪© Keren Kalif‬‬
‫מבני הנתונים מה‪ STL -‬שנסקור במצגת זו‬
‫‪ ‬מבני נתונים שהם ‪( Sequences Container‬פניה לאיבר לפי‬
‫מיקומו)‬
‫‪ – vector ‬מימוש למערך שיודע להגדיל את עצמו‬
‫‪ – list ‬מימוש לרשימה מקושרת דו‪-‬כיוונית‬
‫‪ ‬מבני נתונים שהם ‪( Associative Container‬פניה לאיבר לפי‬
‫מפתח)‬
‫‪5‬‬
‫‪ – set ‬מימוש לקבוצה בלי כפילות איברים‪ .‬הנתונים שמורים בעץ‬
‫בינארי‬
‫‪ – multiset ‬כנ"ל‪ ,‬אך מאפשר כפילות איברים‬
‫‪ – map ‬מימוש למפה‪ :‬אוסף של זוגות‪ .key+value :‬לכל ‪ key‬יהיה‬
‫מפתח יחיד‬
‫‪ – multimap ‬כנ"ל‪ ,‬אבל לכל ‪ key‬יכולים להיות כמה מפתחות‬
‫‪© Keren Kalif‬‬
Sequences Container
6
© Keren Kalif
‫‪Sequences Container‬‬
‫‪ ‬לכולם יש את המתודות הבאות (ועוד)‪:‬‬
‫פעולה‬
‫שם המתודה‬
‫)‪ void push_back(const T& val‬מקבלת ערך ומוסיפה העתק שלו לסוף האוסף‬
‫‪ bool empty() const‬מחזירה אמת אם באוסף אין איברים‪ ,‬שקר אחרת‬
‫‪ T front() const‬מחזירה העתק של האיבר הראשון באוסף‪ .‬עף אם האוסף‬
‫ריק‪.‬‬
‫)(‪ void clear‬מרוקנת את כל איברי האוסף‪ .‬עוברת ב‪ d’tor -‬של כל איבר‪.‬‬
‫יש לשים לב שאם האיברים הם מצביעים‪ ,‬אינה משחררת‬
‫אותם‪.‬‬
‫)(‪ void pop_back‬מורידה מהאוסף את האיבר האחרון‪ ,‬ומשחררת אותו‬
‫‪ int size() const‬מחזירה את כמות האיברים באוסף (גודל לוגי)‬
‫=‪ operator‬מימוש אופרטור השמה‬
‫==‪ operator‬פונקציית ‪ friend‬הבודקת האם איברי האוסף זהים (גם‬
‫בסדר)‬
‫‪7‬‬
‫‪© Keren Kalif‬‬
‫‪)2( Sequences Container‬‬
‫‪ ‬ל‪ list -‬יש גם את המתודות הבאות‪:‬‬
‫שם המתודה‬
‫פעולה‬
‫)‪ void push_front(const T& val‬מקבלת ערך ומוסיפה העתק שלו לתחילת האוסף‬
‫)(‪ void pop_front‬מורידה מהאוסף את האיבר הראשון‪ ,‬ומשחררת אותו‬
‫‪ ‬ל‪ vector -‬יש גם את המתודות‪:‬‬
‫שם המתודה‬
‫פעולה‬
‫‪ int capacity() const‬מחזירה את הגודל הפיזי של המערך‬
‫)‪ void reserve(int n‬במידה ו‪ capacity < n -‬מגדילה את ‪ capacity‬בהתאם‪.‬‬
‫משמש לצרכי יעילות‪.‬‬
‫‪8‬‬
‫‪© Keren Kalif‬‬
‫‪)3( Sequences Container‬‬
‫‪ ‬לכולם יש את המתודות הבאות (ועוד)‪:‬‬
‫פעולה‬
‫שם המתודה‬
‫‪ iterator insert(iterator pos,‬הוספת הערך ‪ val‬לפני האיבר במיקום ‪pos‬‬
‫)‪const T& val‬‬
‫‪ void insert(iterator pos, int n,‬הוספת ‪ n‬ערכים ‪ val‬לפני האיבר במיקום ‪pos‬‬
‫)‪const T& val‬‬
‫)‪ iterator erase(iterator pos‬מסירה את האיבר במיקום ‪ pos‬ומשחררת אותו‬
‫‪ iterator erase(iterator first,‬מסירה את כל האיברים בטווח בין ‪ first‬ל‪( last -‬לא‬
‫)‪iterator last‬‬
‫כולל ‪)last‬‬
‫‪ ‬איטרטורים‪:‬‬
‫שם המתודה‬
‫פעולה‬
‫)(‪ iterator begin‬מחזיר איטרטור לאיבר הראשון באוסף‬
‫)(‪ iterator end‬מחזיר איטרטור לאיבר אחרי האחרון באוסף‬
‫‪9‬‬
‫‪© Keren Kalif‬‬
1. int main()
2. }
3.
vector<int> numbers;
vector -‫דוגמא לשימוש ב‬
// --> Collection is empty!
4.
5.
cout << "Is collection empty? " << numbers.empty() << endl; // --> 1
cout << "size=" << numbers.size() << " capacity="
<< numbers.capacity() << endl;
// --> size=0 capacity=0
6.
7.
numbers.push_back(4);
cout << "size=" << numbers.size() << " capacity="
<< numbers.capacity() << endl;
// --> size=1 capacity=1
8.
9.
10.
numbers.push_back(8);
numbers.push_back(2);
cout << "size=" << numbers.size() << " capacity="
// --> size=3 capacity=3
<< numbers.capacity() << endl;
13.
14.
cout << "Is collection empty? " << numbers.empty() << endl; // --> 0
cout << "size=" << numbers.size() << " capacity="
<< numbers.capacity() << endl;
// --> size=3 capacity=3
// values in the vector: 4 8 2
© Keren Kalif
10
)‫(המשך‬
vector -‫דוגמא לשימוש ב‬
23.
24.
int firstValue = numbers.front();
cout << "first value is " << firstValue << endl;
// first value is 4, values in the vector: 4 8 2
25.
26.
// values in the vector: 4 8
numbers.pop_back();
cout << "size=" << numbers.size() << " capacity="
// --> size=2 capacity=3
<< numbers.capacity() << endl;
27.
28.
numbers.reserve(10);
cout << "size=" << numbers.size() << " capacity="
<< numbers.capacity() << endl;
// --> size=2 capacity=10
29.
30.
numbers.clear();
cout << "size=" << numbers.size() << " capacity="
<< numbers.capacity() << endl; // --> size=0 capacity=10
31. {
© Keren Kalif
11
‫דוגמא לאוסף המכיל‬
‫אובייקטים‬
‫‪12‬‬
‫‪© Keren Kalif‬‬
‫איטרטורים‬
© Keren Kalif
13
‫איטרטורים‬
‫‪ ‬בכל מחלקה המממשת מבנה‪-‬נתונים ב‪ STL -‬ממומשות ‪ 2‬מחלקות‬
‫פנימיות‪ iterator :‬ו‪const_iterator -‬‬
‫‪ ‬איטרטור הוא אובייקט שמכיל הצבעה לאיבר מסויים באוסף‬
‫‪ ‬לכן אנחנו מתייחסים לאיטרטור כמעין מצביע‬
‫‪ ‬מחלקת האיטרטור מספקת מימשק למעבר על כל איברי האוסף‬
‫באופן סדרתי‬
‫‪ ‬בכל מחלקה המממשת מבנה נתונים יש את השיטות‪:‬‬
‫‪ – begin() ‬המחזירה איטרטור לאיבר הראשון באוסף‬
‫‪ – end() ‬המחזירה איטרטור לאיבר אחרי האחרון באוסף‬
‫‪ ‬היתרון‪:‬‬
‫‪ ‬החלפת מבנה‪-‬נתונים אחד באחר לא תגרור שינוי בשימוש‬
‫‪ ‬כאשר מבנה הנתונים עליו רצים הוא ‪ const‬נעבוד עם‬
‫‪14‬‬
‫‪const_iterator‬‬
‫‪© Keren Kalif‬‬
1.
2.
3.
4.
5.
6.
7.
8.
‫דוגמא לשימוש באיטרטור‬
#include <iostream>
using namespace std;
#include <vector>
int main()
}
vector<int> v1;
!= ‫שימוש באופרטור‬
9.
10.
11.
v1.push_back(1);
v1.push_back(3);
v1.push_back(2);
12.
13.
14.
15.
16.
17. {
vector<int>::iterator
vector<int>::iterator
for ( ; itr != itrEnd
cout << *itr << "
cout << endl;
itr
= v1.begin();
itrEnd = v1.end();
++ ‫שימוש באופרטור‬
;
++itr )
";
//// 
 11 3 2
* ‫שימוש באופרטור‬
v1:
itr
1
3
2
itr
itr
itr itrEnd
© Keren Kalif
15
‫שיטות שיש בכל מחלקת ‪iterator‬‬
‫‪ ‬אופרטור ‪++‬‬
‫‪ ‬מקדם את האיטרטור להכיל הצבעה לאיבר הבא באוסף‬
‫‪ ‬אופרטור *‬
‫‪ ‬מחזיר את התוכן של האיבר אליו האיטרטור מכיל הצבעה‬
‫‪ ‬אופרטור ==‬
‫‪ ‬בודק ששני איטרטורים מכילים הצבעה לאותו איבר‬
‫‪ ‬אופרטור =!‬
‫‪ ‬בודק ששני איטרטורים אינם מכילים הצבעה לאותו איבר‬
‫‪16‬‬
‫‪© Keren Kalif‬‬
‫דוגמאות לפונקציות המדפיסות אוספים‬
‫כאשר האוסף עליו אנחנו רצים הוא‬
‫‪ ,const‬או כאשר השיטה היא ‪,const‬‬
‫יש להשתמש ב‪const_iterator -‬‬
‫‪© Keren Kalif‬‬
‫‪17‬‬
‫פונקציית הדפסת כל אוסף‬
‫‪© Keren Kalif‬‬
‫‪18‬‬
insert -‫ וב‬erase -‫דוגמא לשימוש ב‬
1. void main()
2. {
3.
list<int> numbers;
itr:
4.
5.
6.
numbers.push_back(1);
numbers.push_back(2);
numbers.push_front(3);
7.
8.
9.
list<int>::iterator itr = numbers.begin();
++itr;
numbers.insert(itr, 4);
10.
11.
numbers.insert(--numbers.end(), 5);
printCollection(numbers);
12.
13.
14.
++itr;
numbers.erase(itr);
printCollection(numbers);
15.
16. }
numbers.erase(itr);
numbers:
3
4
1
5
2
2
2
// crashes! The iterator points to no-where..
© Keren Kalif
19
‫דוגמא למימוש איטרטור‬
‫‪20‬‬
‫‪© Keren Kalif‬‬
Object Function
21
© Keren Kalif
‫מהו ‪Object Function‬‬
‫‪ ‬בשפת ‪ C‬יכולנו להגדיר פונקציה שאחד הפרמטרים שלה הוא‬
‫מצביע לפונקציה‬
‫‪ ‬כלומר‪ ,‬אחד הפרמטרים הוא שם של פונקציה בעלת חתימה‬
‫ספציפית‬
‫‪ ++C ‬היא שפה מכוונת עצמים‪ ,‬ולכן הדגש הוא על אובייקטים‪.‬‬
‫במקום לשלוח שם של פונקציה‪ ,‬נשלח אובייקט שיתאר את‬
‫הפעולה שאנחנו רוצים לבצע‬
‫‪ ‬במחלקה זו נעמיס את האופרטור()‬
‫‪22‬‬
‫‪© Keren Kalif‬‬
‫דוגמא‬
‫הגדרת ה‪ template -‬יכולה להיות או‬
‫אן‬
‫על המחלקה כולה או רק על המתודה‬
‫למחלקות אלו קוראים ‪Object‬‬
‫‪ Function‬משום שתפקידו של‬
‫האובייקט הוא לייצג פעולה‬
‫‪23‬‬
‫‪© Keren Kalif‬‬
‫שימוש ב‪Object Functions -‬‬
‫פונקציה המקבלת ‪ 2‬איטרטורים‬
‫ואובייקט המייצג פעולה‬
‫אובייקטים זמניים‬
‫‪24‬‬
‫‪© Keren Kalif‬‬
‫הפעלת אופרטור () של‬
‫האובייקט ‪ f‬על כל איבר בטווח‬
‫דוגמאת מיון‬
© Keren Kalif
25
‫שימוש במיון‬
‫ניתן לשלוח במקום אובייקט עם העמסת ()‬
‫שם של פונקציה עם חתימה זהה‬
‫‪26‬‬
‫‪© Keren Kalif‬‬
Associative Container
© Keren Kalif
27
‫‪Associative Containers‬‬
‫‪ ‬אלו מבני נתונים אשר ניתן לגשת אליהם עפ"י מפתח‪ ,‬ולא‬
‫בהכרח עפ"י אינדקס (מספר)‪.‬‬
‫‪ ‬מבני נתונים אלו ממוינים עפ"י המפתח‪ ,‬לכן צריך לספק עבורם‬
‫מתודה השוואה‪ .‬במידה ולא נספק‪ ,‬מבנה הנתונים ישתמש ב‪-‬‬
‫‪ ,default‬אם קיים‪ ,‬אחרת יתן שגיאת קומפילציה‬
‫‪28‬‬
‫‪© Keren Kalif‬‬
‫‪set‬‬
‫‪ set ‬הוא מבנה נתונים לשמירת מפתחות בלבד‪ .‬כל מפתח הוא‬
‫יחודי‪ .‬נסיון הוספה של מפתח קיים לא יבוצע‪.‬‬
‫‪ ‬איברי ה‪ set -‬ממוינים ומוחזקים בעץ בינארי‬
‫‪multiset‬‬
‫‪ ‬כמו ‪ set‬אך כל מפתח יכול להיות קיים יותר מפעם אחת‬
‫‪ ‬כאשר נוריד איבר מהקבוצה‪ ,‬במידה וקיימים כמה העתקים‪ ,‬ירד‬
‫רק מופע אחד שלו‬
‫‪29‬‬
‫‪© Keren Kalif‬‬
1.
#include <set>
‫ דוגמא‬- set
2. void main()
3. }
4.
set<int> intSet;
5.
6.
intSet.insert(4);
intSet.insert(2);
intSet.insert(1);
7.
intSet.insert(3);
intSet.insert(1);
8.
printCollection(intSet); // 1 2 3 4
9.
10.
cout << "Is set empty? " << intSet.empty() << endl; // Is set empty? 0
11.
cout << "Value 1 appears " << intSet.count(1) << " times\n";
12.
// Value 1 appears 1 times
13.
cout << "Value 8 appears " << intSet.count(8) << " times\n";
14.
// Value 8 appears 0 times
15.
intSet.erase(2);
16.
printCollection(intSet); // 1 3 4
17.
cout << "There are " << intSet.size() << " values in the set\n";
18.
// There are 3 values in the set
19.
cout << "There can be max" << intSet.max_size() << " elements\n";
20.
// There can be max 1073741823 elements
21.
set<int>::iterator itr = intSet.find(4);
22.
if (itr != intSet.end())
23.
cout << "4 is found\n"; // 4 is found
24.
25.
26. }
intSet.clear();
printCollection(intSet); // There cam be maximum can be 1073741823
© Keren Kalif
30
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
)2( ‫ – דוגמא‬set
#include <iostream>
using namespace std;
#include <set>
template <class T>
void printCollection(const T& collection)
{ … }
void main()
}
char* words[] = {"shalom", "kita", "alef", "shalom", "kita", "beit"};
set<char*> wordsSet;
19.
20.
21.
22. {
int numOfWords = sizeof(words)/sizeof(words[0]);
for (int i=0 ; i < numOfWords ; i++)
wordsSet.insert(words[i]);
printf("The words in the set:\n");
printCollection(wordsSet); // beit alef kita shalom
wordsSet.clear();
printf("The words in the set after clear:\n");
printCollection(wordsSet); // Collection is empty!
,‫ היא אוסף ממוין‬set ‫ההגדרה של‬
...‫אך בפועל אנחנו רואים שלא‬
© Keren Kalif
31
‫מיון ‪set‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫בדוגמא הקודמת ראנו שאיברי ה‪ set -‬אינם ממוינים כצפוי‬
‫‪ set‬ממיין את איבריו בעזרת האופרטור >‬
‫מאחר ואיברי ה‪ set -‬בדוגמא הקודמת הם מטיפוס מצביע‪ ,‬המיון‬
‫נעשה לפי כתובתם‪ ,‬ולא לפי תוכנם‬
‫במידה ולא ממומש אופרטור > עבור ‪ ,T‬נקבל שגיאת קומפילציה‬
‫ניתן להגדיר ‪ set‬ולספק כארגומנט אובייקט שייצג את פונקציית‬
‫ההשוואה‬
‫‪ ‬כאמור‪ ,‬אובייקט כזה נקרא ‪ object function‬ונממש עבורו את‬
‫האופרטור ()‬
‫‪32‬‬
‫‪© Keren Kalif‬‬
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
#include <iostream>
using namespace std;
#include <set>
)2( ‫ – דוגמא‬set ‫מיון‬
template <class T>
void printCollection(const T& collection) {…}
‫אובייקט המעמיס את אופרטור () ויודע‬
class ltstr
‫להשוות בין שני משתנים מטיפוס מחרוזת‬
}
public:
bool operator()(const char* s1, const char* s2) const
{return strcmp(s1, s2) < 0;}
};
int main()
{
char* words[] = {"shalom", "kita", "alef", "shalom", "kita", "beit"};
int numOfWords = sizeof(words)/sizeof(words[0]);
set<char*, ltstr> wordsSet;
for (int i=0 ; i < numOfWords ; i++)
wordsSet.insert(words[i]);
‫יצירת האובייקט תכלול את‬
‫האובייקט שיודע לבצע את ההשוואה‬
printf("The words in the set:\n");
printCollection(wordsSet); // alef beit kita shalom
{
© Keren Kalif
33
‫‪map‬‬
‫‪ ‬מבנה נתונים המכיל זוגות של ‪ key‬ו‪value -‬‬
‫‪ ‬לכל ‪ key‬יש מפתח יחיד‪ .‬ניסיון הכנסה נוספת של ‪ key‬קיים תדרוס‬
‫את ה‪ value -‬המקורי‬
‫‪ ‬בעת הכנסה של ‪ key‬קיים‪ ,‬יש לבדוק האם צריך לשחרר את הזיכרון‬
‫של ה‪ value -‬הנוכחי‬
‫‪multimap‬‬
‫‪ ‬כמו ‪ map‬אך כל מפתח יכול להיות קיים יותר מפעם אחת‬
‫‪ ‬כאשר נוריד מפתח‪ ,‬ירד ה‪ value -‬הראשון‬
‫‪34‬‬
‫‪© Keren Kalif‬‬
map -‫דוגמא לשימוש ב‬
© Keren Kalif
35
)2( map -‫דוגמא לשימוש ב‬
© Keren Kalif
36
‫דוגמא נוספת לשימוש ב‪map -‬‬
‫(מתוך ‪)STL Reference‬‬
‫‪37‬‬
‫האיברים מסודרים הפוך לסדר הכנסתם‬
‫‪© Keren Kalif‬‬
multimap -‫דוגמא לשימוש ב‬
© Keren Kalif
38
‫אלגוריתמים‬
© Keren Kalif
39
‫אלגוריתמים שנסקור‪:‬‬
‫‪ min_element, max_element‬‬
‫‪ sort‬‬
‫‪ reverse‬‬
‫‪ swap, itr_swap‬‬
‫‪ find, find_if‬‬
‫יש להוסיף‪:‬‬
‫>‪#include <algorithm‬‬
‫אלו פונקציות גלובליות‪ ,‬שהסינטקס של רובן הוא‬
‫ששני הפרמטרים הראשונים שלהן הם טווח‬
‫איברים עליהם תבוצע הפעולה (לרוב‪ ,‬איטרטור‬
‫‪ begin‬ואיטרטור ‪(end‬‬
‫‪40‬‬
‫‪© Keren Kalif‬‬
‫‪ count, count_if‬‬
‫‪ for_each‬‬
‫‪ transform‬‬
‫‪ copy‬‬
min_element, max_element
1.
2.
#include <iostream>
using namespace std;
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
‫הפונקציות מקבלות איטרטור‬
‫ ומחזירות‬end -‫ ו‬begin
‫איטרטור לאיבר המתאים‬
> ‫ יועמס האופרטור‬T -‫דורשות של‬
vector<int>::iterator max = max_element(numbers.begin(), numbers.end());
cout << "The max is " << *max << endl; // --> The max is 7
vector<int>::iterator min = min_element(numbers.begin(), numbers.end());
cout << "The min is " << *min << endl; // --> The min is 1
{
© Keren Kalif
41
sort
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
end -‫ ו‬begin ‫הפונקציה מקבלת איטרטור‬
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
> ‫ יועמס האופרטור‬T -‫דורשת של‬
// 4 1 7 4 2 5
sort(numbers.begin(), numbers.end());
{
// 1 2 4 4 5 7
© Keren Kalif
42
reverse
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
end -‫ ו‬begin ‫הפונקציה מקבלת איטרטור‬
‫הפונקציה מקבלת שני משתנים מאותו‬
‫ומשתמשת באופרטור= שלהם‬
// 4 1 7 4 2 5
reverse(numbers.begin(), numbers.end());
{
// 5 2 4 7 1 4
© Keren Kalif
43
swap
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
void main()
{
int x=2, y=3;
swap(x, y);
‫הפונקציה מקבלת שני משתנים מאותו‬
‫ומשתמשת באופרטור= שלהם‬
// x=2, y=3
// x=3, y=2
{
char str1[10]=“hello”, str2[10]=“world”;
swap(str1, str2);
// doesn’t compile,
can’t change addresses
© Keren Kalif
44
itr_swap
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
itr_swap(numbers.begin(),
{
‫ איטרטורים‬2 ‫הפונקציה מקבלת‬
‫ומחליפה את תוכנם‬
T ‫הפונקציה משתמשת באופרטור= של‬
// 4 1 7 4 2 5
++(numbers.begin());
// 1 4 7 4 2 5
© Keren Kalif
45
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
find
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
, begin ‫הפונקציה מקבלת איטרטור‬
‫ ומחזירה‬,‫ ואיבר לחיפוש‬end ‫איטרטור‬
‫איטרטור לאיבר הראשון באוסף שזהה לאיבר‬
== ‫ יועמס האופרטור‬T -‫דורשת של‬
vector<int>::iterator found = find(numbers.begin(), numbers.end(), 8);
if (found == numbers.end())
cout << "value doesn't exist\n";
else
cout << "value exists\n";
found = find(numbers.begin(), numbers.end(), 7);
if (found == numbers.end())
cout << "value doesn't exist\n";
else
cout << "value exists\n";
{
© Keren Kalif
46
1.
2.
3.
4.
#include <algorithm>
#include <vector>
bool isOdd(int num) {return num%2==1;}
find_if
‫ אפשר לשלוח‬,‫במקום פונקציה‬
Object Function ‫גם‬
5. int main()
6. {
7.
vector<int> numbers;
8.
‫ איטרטור‬, begin ‫הפונקציה מקבלת איטרטור‬
9.
numbers.push_back(4);
‫ ומחזירה‬T ‫ ושם של פונקציה המקבלת‬end
10.
numbers.push_back(1);
‫ ומחזירה איטרטור לאיבר הראשון‬,bool
11.
numbers.push_back(7);
true ‫באוסף שהפעלת הפונקציה עליו מחזירה‬
12.
numbers.push_back(4);
13.
numbers.push_back(2);
14.
numbers.push_back(5);
== ‫ יועמס האופרטור‬T -‫דורשת של‬
15.
16.
vector<int>::iterator found =
17.
find_if(numbers.begin(), numbers.end(), isOdd);
18.
19.
if (found == numbers.end())
20.
cout << “No value is odd\n";
21.
else
22.
cout << "value exists: " << *found << "\n"; // value exists: 1
23. {
© Keren Kalif
47
count
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
int main()
{
vector<int> numbers;
numbers.push_back(4);
numbers.push_back(1);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
, begin ‫הפונקציה מקבלת איטרטור‬
‫ ומחזירה‬,‫ ואיבר לחיפוש‬end ‫איטרטור‬
‫את כמות המופעים שלו באוסף‬
== ‫ יועמס האופרטור‬T -‫דורשת של‬
int num4 = count(numbers.begin(), numbers.end(), 4);
cout << "4 appears " << num4 << "times\n"; // 4 appears 2 times
{
© Keren Kalif
48
count_if
1.
2.
3.
4.
5.
#include <iostream>
using namespace std;
6.
bool isOdd(int num) {return num%2==1;}
#include <algorithm>
#include <vector>
7. int main()
8. {
‫ איטרטור‬, begin ‫הפונקציה מקבלת איטרטור‬
9.
vector<int> numbers;
‫ ומחזירה‬T ‫ ושם של פונקציה המקבלת‬end
10.
‫ ומחזירה את כמות האיברים באוסף‬,bool
11.
numbers.push_back(4);
true ‫שהפעלת הפונקציה עליהם מחזירה‬
12.
numbers.push_back(1);
13.
numbers.push_back(7);
14.
numbers.push_back(4);
== ‫ יועמס האופרטור‬T -‫דורשת של‬
15.
numbers.push_back(2);
16.
numbers.push_back(5);
17.
18.
int numOfOdd = count_if(numbers.begin(), numbers.end(), isOdd);
19.
cout << "There are " << numOfOdd << " odd values\n";
20.
// There are 3 odd values
49
21. {
© Keren Kalif
for_each
1.
2.
3.
4.
5.
6.
7.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
void print(int num) {cout << num << " ";}
8. int main()
9. {
10.
vector<int> numbers;
‫ איטרטור‬, begin ‫הפונקציה מקבלת איטרטור‬
11.
12.
numbers.push_back(4);
‫ ושאינה‬T ‫ ושם של פונקציה המקבלת‬end
13.
numbers.push_back(2);
‫ מפעילה את הפונקציה‬for_each .‫מחזירה דבר‬
14.
numbers.push_back(7);
‫שהתקבלה על כל אחד מאיברי הטווח‬
15.
numbers.push_back(4);
16.
numbers.push_back(2);
17.
numbers.push_back(5);
18.
19.
for_each(numbers.begin(), numbers.end(), print);
// 4 2 7 4 2 5
20. {
© Keren Kalif
50
transform
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include <algorithm>
#include <vector>
#include <list>
,‫שולחת כל איבר בטווח לפונקציה המבוקשת‬
‫ואת התוצאה מוסיפה לאוסף השני‬
int square(int num) {return num*num;}
int main()
{
std::list<int>
std::vector<int>
15.
16.
17.
18. }
intList;
intArr;
for (int i=1; i<=5; ++i)
intList.push_back(i);
// intList: 1 2 3 4 5
// int arr:
std::transform (intList.begin(), intList.end(),
std::back_inserter(intArr),
square);
‫הפונקציה לחישוב‬
‫טווח איברים עליו נעבוד‬
‫האוסף אליו נוסיף את‬
‫התוצאה ומיקום ההוספה‬
// intList: 1 2 3 4 5
// int arr: 1 4 9 16 25
© Keren Kalif
51
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
copy
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <list>
‫הפונקציה מקבלת טווח איטרטורים וסדר‬
‫) ומוסיפה‬front/back( ‫הוספה לאוסף אחר‬
‫את כל האיברים בטווח לאוסף האחר‬
int main()
{
vector<int> numbers;
list<int> frontIntList, backIntList;
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
copy(numbers.begin(), numbers.end(), back_inserter(backIntList));
copy(numbers.begin(), numbers.end(), front_inserter(frontIntList));
{
// backIntList: 4 2 7 4 2 5
// frontIntList: 5 2 4 7 2 4
© Keren Kalif
52
‫ לצורך הדפסה‬copy -‫שימוש ב‬
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <list>
int main()
{
vector<int> numbers;
list<int> frontIntList, backIntList;
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(7);
numbers.push_back(4);
numbers.push_back(2);
numbers.push_back(5);
‫ כותב איברים מטיפוס‬ostream_inserter
‫ עם מפריד '_' בין האיברים‬,‫ למסך‬T
copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, "_"));
printf(“\n”);
{
© Keren Kalif
53
string ‫המחלקה‬
© Keren Kalif
54
‫ביחידה זו למדנו‪:‬‬
‫‪ ‬סקירת ה‪STL -‬‬
‫‪ ‬סוגים של ‪'conatiner‬ים‬
‫‪ ‬איטרטור‬
‫‪Object Functions ‬‬
‫‪ ‬אלגוריתמים‬
‫‪ ‬המחלקה ‪string‬‬
‫‪55‬‬
‫‪© Keren Kalif‬‬