960 likes | 1.23k Views
Advanced STL. Overview of Containers, Iterators, Algorithms. Using Functionality in STL. Learning & Development Team. http://academy.telerik.com. Telerik Software Academy. Table of Contents (1). Containers Concepts Priority queue (multi)Sets, (multi)Maps Iterators Concepts
E N D
Advanced STL Overview of Containers, Iterators, Algorithms. Using Functionality in STL Learning & Development Team http://academy.telerik.com Telerik Software Academy
Table of Contents (1) • Containers • Concepts • Priority queue • (multi)Sets, (multi)Maps • Iterators • Concepts • STL container iterators • Insertion iterators and iterators on streams
Table of Contents (2) • Algorithms • Heap creation • Sorting, Operations on sorted containers • Searching • Combinatorial • Functors • Concepts • Creating and using Generators, Unary and Binary Functors
Containers STL Container Architecture, Advanced Containers
Containers • STL Containers represent collections of objects • Going through objects is called iterating • Several base concepts & refinements for all STL containers: • Container • Forward Container, Reversible Container • Random Access Container • Concepts – definitions, not implementations • Refinements – extensions/specific definitions
Containers • Containers also fall into one of two groups: • Sequences • Associative containers • Actual data structures are models of the above • i.e. implementations of the Concepts • e.g. a vector is a model of a Sequence
Containers – Pseudo-Diagram Container Forward, Reversible, Random Access Sequence Front/Back Insertion Associative Container Simple, Pair, Sorted, Unique list vector map deque set bit_vector Adaptor multimap multiset stack queue priority_queue
Containers • STL Containers are templates • A template is filled compile-time with type data • i.e. a STL container is defined once • compiled into different classes • depending on its passed template parameters • E.g. the container class vector is defined in the header <vector> once, but we can: • use a vector<int>, to store integers • use another vector<string> to store strings, etc.
Containers • Container concept • Stores elements, element lifetime ends when container lifetime ends • No guarantees on element order • Forward Container concept (refinement of Container) • Elements have some order • Order won't change as a side effect of going through (iterating) the elements • Guarantees "forward direction" of iteration
Containers • Reversible Container concept (refinement of Forward Container) • Guarantees two (opposite) directions of iteration – "forward" and "backward" • Random Access Container (refinement of Reversible Container) • Guarantees (amortized) constant time access to any contained element • i.e. can access an element, without iterating other elements to reach it
Sequences • Sequences are refinements of Forward Containers • Have a definite ordering of elements • Have variable size – elements can be added indefinitely, at specific positions • Sequence models: • vector • list • deque
Associative Containers • Associative Containers are Containers • Similar to Sequences, but cannot add elements at specific positions • Each element has a key and a value • Elements are accessed by their key • Elements can be added indefinitely, but the container decides their "position" • Several types (to be discussed later)
Container Adaptors • Adaptors limit access to containers • Fundamental for FIFO and LIFO data structures • Adaptor models: • queue • stack • priority_queue
Advanced Container Models priority_queue, map, set, multimap, multiset, Usage and Examples Note: for basic container models, see Basic ADTs in STL
Priority Queue • The priority_queue is a queue • Enables insertion of elements • Enables access/removal of "top" element • "First" element is referred to as "top" element • Guarantees the top element is the largest • Biggest for numbers (by default) • Last lexicographically for strings (by default) • Or according to a comparer • Or overloaded operators for other types
Priority Queue • Priority Queue (#include <queue>) • priority_queue<T, Sequence = vector<T>, Compare = less<T> > • T has to be able to be compared by Compare • Fast at accessing the top element (1) • Fast at inserting elements (log n) • Good at removing top element (log n) • Uses a container for storing elements (default: vector)
Priority Queue • Declaring and initializing a priority queue: • Retrieving top element: • Removing top element: #include<queue> //required header … priority_queue<int> numsBySize; numsBySize.push(1); numsBySize.push(3); numsBySize.push(2); priority_queue<string> stringsByLex; stringsByLex.push("a"); stringsByLex.push("c"); stringsByLex.push("b"); numsBySize.top() //returns 3, does not remove it stringsByLex.pop() //removes "c"
Priority Queue Usage Live Demo
Problems Solved with Priority Queues • Finding shortest path in weighted graphs (Dijkstra's algorithm uses priority queues) • Getting largest N items from several sorted lists • Compression in Huffman coding • Heapsort (STL priority queue uses a heap) • Simple problem: • Given a sequence of numbers, each time a numbers is 0, print the largest number so-far
Associative Container Models • Several categories • Simple, Sorted, Unique • Simple Associative Containers • Elements are their own keys • Pair Associative Container • Values are in the form (key, element) • Sorted Associative Containers • Elements ordered, most operations are log n • Unique Associative Containers • No duplicate keys are allowed
Set • Categories: Sorted, Simple, Unique • Elements are their own keys • E.g. if you want to check if an element is contained, you query with the (copy) of the element • Guarantees no duplicate elements • Extracting elements one by one: • Yields the elements in ascending order
Set • Set (#include <set>) • set<Key, Compare = less<Key>, Alloc = new> • Key has to be comparable by Compare • Fast checking if an element is contained (log n) • Fast inserting elements (log n) • Fast deleting (erasing) elements (log n) • Deleting elements does not invalidate iterators to other elements
Set • Declaring and initializing a set: • Set elements can be accessed through iterator (and consequently iterated in ascending order) • Set elements can be removed • By iterator • By value #include<set> //required header … set<int> uniqueNums; uniqueNums.insert(3); uniqueNums.insert(7); uniqueNums.insert(2); uniqueNums.insert(7); uniqueNumbers.begin(); //iterator to first element (2) uniqueNums.erase(uniqueNums.begin()); uniqueNums.erase(2);
Set Usage Live Demo
Problems Solved with Sets • Any problems including mathematical set operations • Unions, intersections, etc. • Set Cover Problem • Simple problem: • You are given a sequence of numbers. Print all numbers in the sequence, without printing the same number more than once
Simple Problem Solved with a Set Live Demo
Multiset • Same as a set, without the Unique category • i.e. there can be repeating elements • All other operations & properties are the same • Multiset (#include <set>) • multiset (same template parameters as set) • Declaring and initializing a multiset #include<set> //required header … multiset<int> nums; nums.insert(2); nums.insert(2); //nums contains: 2, 2
Multiset Usage Live Demo
Map • Categories: Sorted, Unique, Pair • Each element has a key • Accessing elements is done through the key • Guarantees no duplicate elements • Element keys are iterated in increasing order • Often pictured as an array, the indices of which can be any type – number, string or even some class
Map • Map (#include <map>) • map <Key, Data, Compare = less<Key>Alloc = new> • Key must be comparable by Compare • Fast at accessing elements by key (log n) • Fast at deleting elements by key (log n) • Fast at inserting elements by key (log n) • Values are of the type std::pair<Key, Data> • Iterators will point to std::pair objects
Map • Declaring and initializing a map: • Accessing element by key: • Removing element by key: #include<map> //required header … map<char*, int> peopleAges; peopleAges["Joro"] = 22; peopleAges.insert(pair<char*, int>("Petya", 20)); peopleAges["Petya"]; peopleAges["Petya"]++; peopleAges.erase("Joro");
Map Usage Live Demo
Problems Solved with Maps • Maps have similar efficiency as hash-tables, but keep elements ordered • Many compression algorithms use maps/hash-tables • Several cryptographic attacks use maps/hash-tables • Simple Problem: • You are given a sentence of words. Count how many times each word occurs in the text.
Simple Problem Solved with a Map Live Demo
Multimap • Same as a map, without the Unique category • i.e. there can be repeating elements • No [] operator, as there can be multiple values, corresponding to the same key • All other operations & properties are the same • Most element access is done through iterators
Multimap • Multimap (#include <map>) • multimap(same template parameters as map) • Declaring and initializing a multimap #include<map> //required header … multimap<string, string> personNicks; personNicks.insert(pair<string, string>("George", "Joro")); personNicks.insert(pair<string, string>("George", "Gosho")); personNicks.insert(pair<string, string>("George", "Joro")); personNicks.insert(pair<string, string>("George", "Gopi"));
Multimap Usage Live Demo
Iterators The Way of STL Element Access
Iterators • Iterators are a pattern in STL • Enable access to container elements • For almost any container's elements • Most container iterators have similar mechanics to pointers • Can be incremented, to point to next element • Can be dereferenced, to get element value • Can use ->operator to access element members • Can be const
Iterators • Each container defines its own iterator type • A class inside the container's class • Syntax to access iterator type • Example for an iterator of a vector<int>: container_type<template_parameters...>::iterator vector<int> numbers; numbers.push_back(1); numbers.push_back(2); vector<int>::iterator numsIter = numbers.begin(); cout<<*numsIter<<endl; numsIter++; cout<<*numsIter<<endl;
Iterators: Simple Example Live Demo
Iterators and Containers Syntax, Usage, Examples
Iterators • Several types of iterator Concepts • with differing purposes and functionality • Output Iterator • Supports storing values • i.e. writing values to the pointed element • i.e. mutable • Supports incrementing • Other operations are not necessarily supported • i.e. no guarantee on dereferencing, comparing…
Iterators • Input Iterator • Supports dereferencing • Supports incrementing • Does not necessarily support storing values • i.e. writing values to the pointed element • i.e. not necessarily mutable • Opposite of Output iterator, in some sense
Iterators • Forward Iterator • Refinement of Input & Output iterators • Reflects the idea of a linear sequence of values • Allows multipass algorithms • Implementations can be mutable/immutable • Can only increment, i.e. can't "go back", only "forward"
Iterators • Bidirectional Iterator • Refinement of Forward Iterator • Can be both incremented and decremented • i.e. allows "going back"
Iterators • Random Access Iterator • Refinement of Bidirectional Iterator • Constant-time moving in arbitrarily-sized steps • i.e. can increment/decrement with any value, not just 1 step like other iterators • e.g. increment a random access iterator 5 steps: • Note: using vector iterator, as it is a Random Access Iterator vector<int>::iterator iter = someVector.begin(); iter+=5;
Iterators and Containers • Most container operations require iterators or return iterators • erase(), find(), insert() to name a few • Some containers require iterators • To access elements in a meaningful way • list, set, multiset, multimap • Iterating over maps/sets • Gives the elements in order • Note: Container iterators are at least Forward
Iterators and Containers • Iterating a container • i.e. go through container elements with iterator • Instantiate an iterator of the container's type • Set it to the beginning (usually .begin()) • Start a loop, incrementing the iterator • Stop if the iterator equals .end() of container • end()– iterator pointing "after the last element" • At each step, the iterator will point to an element (unless you've reached end())