נסתכל כעת על עוד אוסף שיש לנו בספריה הסטנדרטית והוא .
זהו אוסף המממש רשימה מקושרת דו כיוונית אשר מאפשרת:
- הוספת איברים מהירה לכל מקום ברשימה.
- גישה סדרתית קדימה ואחורה ברשימה
הרשימה אינה מאפשרת גישה מהירה למקום שרירותי בה.
חלקים גדולים מהממשק של ו- משותפים וגם השימוש בממשק דומה, מה שמאפשר למשתמש להחליף בקלות את סוג האוסף שהוא משתמש בו, גם בשלב מאוחר בתכנות.
בפועל, הוא פתרון פשוט ויעיל ברוב המקרים ומומלץ להשתמש בו.
נסתכל על שיטות נבחרות מהמחלקה:
template <typename T>
class list
{
list();
list(const list& c);
list(size_t num, const T& val = T());
list& operator=(const list& c);
~list();
void push_back(const T& val);
void pop_back();
void push_front(const T& val);
void pop_front();
size_t size() const;
};
היצור הבא שנסתכל עליו הוא אשר הינו בעצם תור דו כיווני.
הוא כמו וקטור אך מאפשר הכנסה והוצאה מהירה משני הקצוות.
הממשק גם הוא דומה מאוד לוקטור.
deque<string> words = { "Hello", "World" };
words.pop_front();
words.push_front("Hi");
נסתכל כעת על שני מבנים אסוציאטיביים אשר בהם סדר ההכנסה לא משפיע על סדר האיטרציה על האיברים:
- הראשון מביניהם יהיה השומר על איבריו בסדר ממוין באמצעות .
מבנה הנתונים זה מממש קבוצה ולכן אין בו כפילויות. - מבנה הנתונים שומר זוגות של כאשר יש לכל היותר זוג אחד עם כל מפתח. (אין כפילויות מפתח)
ניתן לבצע איטרציה על הזוגות השמורים ב- וניתן להשתמש ב- כדי לגשת לזוג עם מפתח נתון, כדי לשנות ערך השייך למפתח או כדי להכניס זוגות חדשים.
ניתן בנוסף למצוא איבר באמצעות השיטה אשר במידה והמפתח קיים, יוחזר האיטרטור המצביע לצמד המבוקש ובמידה ולא קיים, יוחזר איטרטור לסוף מבנה הנתונים המייצג כשלון או הצבעה לא חוקית.
נקבל קלט מהמשתמש ונספור את המילה הכי נפוצה שמופיעה בקלט.
void mostFequentWord()
{
string word;
map<string, int> count;
int maxCount = 0;
string maxWord = 0;
while (cin >> word)
{
count[word]++;
if (count[word] > maxCount)
{
maxCount = count[word];
maxWord = word;
}
}
cout << maxWord << endl;
}
איטרטורים והספריה הסטנדרטית
כמעט כל האוספים בספרייה הסטנדרטית מספקים איטרטור בעזרתו ניתן לעבור על איבריהם. האיטרטור מאפשר לנו גם לכתוב קוד אחיד אשר יכול לפעול על מספר אוספים.
כל אוסף מגדיר גם אשר ניתן באמצעותו לעבור על מבנה קבוע.
ניתן לקבל איטרטור קבוע למבנה לא קבוע באמצעות .
אוספים שונים מספקים איטרטורים שונים:
- האיטרטור של הוא מסוג דו כיווני המאפשר ו-.
- האיטרטור של וקטור הוא מסוג גישה רנדומלית ומאפשר בנוסף לפעולות הנ"ל גם קידום ונסיגה עם מספר שלם כלשהו וגם גישה עם האופרטור .
- התיעוד של הספרייה הסטנדרטית מציין לכל אוסף את סוג האיטרטור שהוא מספק.
הספרייה
האיטרטורים שראינו זה עתה מאפשרים לנו להשתמש בממשק אחיד למספר אוספים ובנוסף, הספרייה הסטנדרטית מכילה מימושים מובנים למספר אלגוריתמים הפועלים על איטרטורים.
template <class Iterator, class T>
int std::count(Iterator first, Iterator last, cost T& value);
vector<int> numbers = {1, 5, 2, 5, 7};
cout << count(numbers.begin(), numbers.end(), 5); // prints 2
השימוש בספריה דורש את השורה #include <algorithem>.
חלק מהאלגוריתמים דורשים תמיכה בפעולות מסויימות מצד האיטרטורים. למשל, הפעולה דורשת שלאיטרטור יהיה .
האלגוריתמים משתמשים תמיד במימוש היעיל ביותר לפי הפעולות שהאיטרטור תומך בהן.
חלק מהאלגוריתמים ניתנתים להתאמה באמצעות פרמטרים שלהם, למשל, מציאת כל האיברים המקיימים פרדיקט כלשהו ע"י הפונקציה .