C++ Unit 6
C++ Unit 6
We have studied about the template that enables us to do generic programming. Generic
functions or classes support all data types. The standard template library is an advance application
of templates. It contains several in-built functions and operators that help the programmer develop
complex programs.
The programmer only needs to include an appropriate header file to use the function or
operator from the file, such as library functions.For example, if a programmer wants to create a link
list, he/she may require to write a program that may be of 40 to 50 lines. However, using STL
functions (list algorithm), it is a task of a few minutes.
TL is vast and heterogeneous collection of reusable container classes. It consists of vectors,
lists, queues, and stacks. The STL is portable with various operating systems.he STL provides well-
coded and compiled data structures and functions that are helpful in generic programming; and it is
reusable.STL contents are defined in the namespace std. It is essential to write the statement using
namespace std at the beginning of the program.
The STL is divided into three parts. They are containers, algorithms, and iterators. All
these three parts can be used for different programming problems, and are closely associated with
one another.
Containers: A container is an object that contains data or other objects. The standard C++ library
has a number of container classes.These containers support generic programming and can be used
for handling the data of different data types. All STL container classes are declared in namespace
std; There are two types of containers, as shown in figure
• Sequence containers are created to allow sequential and random access to members.
• Associative containers allow access to their elements through a key.
Algorithms: An algorithm is a technique that is useful to handle the data stored in containers. The
STL comprises approximately 60 standard algorithms that give support to perform frequent and
primary operations such as copying, finding, sorting, merging, and initializing. The standard
algorithms are defined in the header file <algorithm>
Iterators: An iterator is an object. It behaves exactly similar to a pointer. It indicates or points to
the data element in a container. It is utilized to move between the data items of containers. Iterators
can be incremented or decremented similar to pointers. They link algorithms with containers and
handle the data stored in the containers.
6.3 Containers
1. Sequence containers
2. Associative containers
3. Derived containers
Sequence containers are developed to allow sequential and random access to all the
members. Associative containers are expanded to get their elements by values. Derived
containers such as stacks, queues, and priority queues can be created from various sequence
containers.Containers are shown in figure below
The STL sequence containers allow controlled sequential access to elements. Sequence
containers hold data elements in a linear series, as observed in below figure.Every element is
associated by its location within the series.
Iterators are used to get the elements in all these containers. All these containers have a
different speed.
a) Vectors
We know that an array is used to store similar data elements. Elements of the array are
stored in successive memory locations and are accessed in order from element number 0 onward.
The vector class exactly acts similar to an array. This class is more secure and efficient than arrays.
Vector containers may allocate some extra storage to accommodate for possible growth, and
thus the container may have an actual capacity greater than the storage strictly needed to contain its
elements
All the elements are accessed randomly; that is, they support random access to individual
elements.A vector container class provide quick access to its elements in sequence. It is used to
insert or delete an element at the end
It is defined in the header file <vector>. A vector is able to enlarge itself. For example, if a
vector declared for 5 elements is assigned 6 elements, then the vector automatically develops its
size so that it can hold the 6th element.The vectors that hold integers and floats are declared as
follows:
#include<vector>
....
vector<int> vi // for integer elements
vector <float> vf // for float elements
b) Lists
The list container enables the programmer to perform the usual deletion and insertion of
items. A list is also a sequence that can be accessed bi-directionally but no direct random access.. It
is defined in header file <list>. It acts as a double-linked list. Every node has a connection to both
back and front nodes in the list. The iterator is used to transverse the link.
The list class supports all the member functions of the vector class. The elements in the
linked list are accessed using pointers. The list container has a technique known as an iterator,
which is used to access the elements of the list container. An iterator is similar to a pointer. Example
#include <list>
....
list<int> l(3);
c) Deques
A deque is similar to a multiple-ended vector.A deque is similar is a double ended queue.The
deque class allows allows operations that contains insertion and deletion at one or both ends .IThe
storage of a deque is automatically expanded and contracted as needed.
deque's are not guaranteed to store all its elements in contiguous storage
locations.Elements of a deque can be scattered in different chunks of storage, with the container
keeping the necessary information internally to provide direct access to any of its elements in
constant time and with a uniform sequential interface (through iterators). Example
#include <deque>
....
deque<int> d(20);
6.3.2 Associative containers
The associative container allows attaches key to each and every element and support direct
access to elements using keys.There is no sequential ordering of elements. Data is sorted while
giving input. These containers use tree-like structures to represent elements instead of linked lists.
They facilitate fast searching, insertion, and deletion. Associative containers are divided into four
categories:
1. sets
2. multisets
3. maps
4. multimaps
All the containers listed above hold data elements in a structure called a tree. The tree
provides quick finding, deletions, and insertions. These containers perform very slowly in random
access operations and are inappropriate for sorting operations.
The essential difference between the set and the multiset is that in a set the elements must be
unique, while a multiset permits duplicate elements. Storing any duplicate elements in set is simply
ignored
#include <iostream>
#include <set>
using namespace std;
main()
{
set<int> s;
s.insert(12);
s.insert(10);
s.insert(2);
s.insert(10); //duplicate element
s.insert(12); //duplicate element
#include <iostream>
#include <set>
using namespace std;
main()
{
multiset<int> s;
s.insert(12);
s.insert(10);
s.insert(2);
s.insert(10); //duplicate element
s.insert(12); //duplicate element
Output:
*Note*:set,multisets are associative because the key and the value are the same
6.4 Algorithms
Algorithms are independent template functions. They are not members or friend functions.
They enable the programmer to manipulate the data stored in various containers.
Although each type of container has its functions for performing common operations. In
addition, the STL defines more than 60 standard algorithms to facilitate users to perform extended
and complex operations.
Including the <algorithm> header file, we can use these functions.The STL algorithms
categorized under five types
Non-mutating sequence algorithms enable operations that do not alter the elements in a
sequence.
Operators Use
Output:
for_each()
0123
count()
1
In the above program operation myfunction is applied to each and every element of the
vector.For every myfunction is called to print the value of the vector.Algorithm count is mentioned
with three arguments vi.begin() represent beginning element of the vector,vi.end() represent
ending element of the vector, and 3 represent element that needs to count
2) Mutating
Mutating sequence algorithms enable operations that alter the elements in a sequence.
Program that fills a vector with random numbers,and demonstrate reverse and replace.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void myfunction (int i) { cout << ' ' << i; }
int main()
{
vector<int> vi(8);
fill(vi.begin(),vi.begin() + 2,5);
fill(vi.begin()+2,vi.begin() + 4,6);
fill(vi.begin()+4,vi.end(),7);
for_each(vi.begin(),vi.end(), myfunction);
Output:
for_each()
55667777
reverse
77776655
replace
11116655
The algorithm fill() is used. The fill() is a mutating algorithm, because it changes the
elements of the vector. The following statements are used to fill the element in the vector:
fill(vi.begin(),vi.begin() + 2,5);
The above statement fills the first 2 elements with the value 5. The function begin() gives a
beginning reference, and begin() + 2 gives a reference for the second.
fill(vi.begin()+2,vi.begin() + 4,6);
The above statement fills the value 6 at the third and fourth locations of the vector. Here
also, the begin() function is used.
fill(vi.begin()+4,vi.end(),7);
The above statement fills the value 7 from location number 5 to the end.
3) Sorting
List of sorting operations on containers is given as
Operators Use
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
cout<<"\nEnter No of elements\n";
cin>>n;
vector<int> vi(n);
cout<<"\nEnter elements\n";
for ( int j=0;j<n;++j)
cin>>vi[j];
cout<<"\nsort() \n";
sort (vi.begin(),vi.begin()+n);
for_each(vi.begin(),vi.end(), myfunction);
}
Output:
Enter No of elements
8
Enter elements
1 0 23 6 66 12 3 33
Partial sort()
0 1 3 23 66 12 6 33
sort()
0 1 3 6 12 23 33 66
4) Set
List of operations on the set is given as
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
void myfunction (int i)
{
cout << ' ' << i;
}
main()
{
set<int> s1;
s1.insert(12);
s1.insert(10);
set<int> s2;
s2.insert(2);
s2.insert(3);
set<int> s;
set_union(s1.begin(), s1.end(),s2.begin(), s2.end(),inserter(s, s.begin()));
cout<<"\n Union of s1,s2 is:\n";
for_each(s.begin(),s.end(), myfunction);
}
Output:
In the above program two sets s1,s2 are created with some elements.Using set_union
elements of s1 and s2 are unionized and placed in set s.
5) Relational
#include <iostream>
#include<vector>
#include <algorithm>
using namespace std;
main()
{
vector<int> e1;
e1.push_back(5);
e1.push_back(8);
e1.push_back(9);
vector<int> e2;
e2.push_back(5);
e2.push_back(8);
e2.push_back(9);
vector<int>::iterator it;
it=max_element( e1.begin(),e1.end() );
cout<<"\nMaximum Element in vector:"<<*it;
it=min_element( e1.begin(),e1.end() );
cout<<"\nMinimum Element in vector:"<<*it;
Output:
Min:a
Max:b
Maximum Element in vector:9
Minimum Element in vector:5
In the above program two vectors v1,v2 are created with some elements.Using equal()
method elements of v1 and v2 are compared.Minimum and maximum of two values (a,b) is
obtained using min() and max() methods.Largest and smallest elements of vector v1 is obtained
using max_element(), methods
6.4 Iterators
Iterators are pointer-like entities that are used to access the elements stored in the container.
Iterators are basically used for traversing the elements of container. This process of traversing from
one element to the next is called iterating through the container. STL offers five types of iterators
input , output, forward, bi-directional, and random access. Basic operations of these iterators is
given as
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<char> lst;
for(char chs='A'; chs<='Z'; ++chs)
lst.push_back(chs);
list<char>::iterator pos;
Output:
ABCDE FGHIJKLMNOPQRSTUVWXYZ
In the above program, lst is an object of type list. The member function push_back() adds a
number in the list. In the for loop, the statement pos = lst.begin(); initializes iterator with the
beginning reference of the list (reference of the first element). The second statement pos !=
lst.end() continues the loop until the pos points to the last element of the list. The statement ++pos
dereference the iterator so that successive numbers are accessed.
6.5 Vectors
A vector is a more useful container. Similar to an array,it also stores elements in neighboring
memory locations. Each element can be directly accessed using the operator[]. A vector is able to
enlarge its size if an extra element is assigned to it. The vector class supports various functions and
they are listed in below table
Function Use
#include<iostream>
#include<vector>
using namespace std;
void show(vector<int> &l) {
vector<int> :: iterator it;
for(it = l.begin(); it != l.end(); ++it)
cout<<*it<<' ';
}
main()
{
vector<int> e;
e.push_back(5);
e.push_back(8);
e.push_back(9);
it =e.end();
e.insert(it,10);
cout<<"\nAfter inserting elements at begin and end: "<<"\n";
show(e);
Output:
In the above program, e is an object of the vector class that can hold data of integer type.
The member function push_back() is used to add the element in the vector object. Three integer
elements 5, 8, and 9 are added to the vector. These elements are stored in contiguous memory
locations. These elements can be accessed in the same manner as we access the array elements. The
vector object name followed by the element number in the [ ] operator displays the specified
number. Here, the overloaded operator [ ] is used.
An iterator it is created to the vector and initialize to beginning and ending of the vector
using it =e.begin() and it =e.end() for insert elements using insert().The same iterator it is
incremented in for loop to display elements in vector.
Finally erase() is used to remove 3rd element in the vector.And the method e.clear() is used
to clear all elements in vector. And the method e.empty() is used to check whether list is empty (or)
not
Example 2:program to display the elements of vector object in ascending and descending
orders using iterators
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
void show(vector<int> &l) {
vector<int> :: iterator it;
for(it = l.begin(); it != l.end(); ++it)
cout<<*it<<' ';
}
main()
{
vector<int> e;
int n,ele;
cout<<"\nEnter number of elements\n";
cin>>n;
cout<<"\nEnter elements\n";
for (int x=0;x<n;x++)
{
cin>>ele;
e.push_back(ele);
}
cout<<"\nElements in ascending order:\n";
sort (e.begin(),e.begin()+n); //sorting elements in descending order
show(e);
Output:
Enter number of elements
4
Enter elements
2 4 0 12
Elements in ascending order:
0 2 4 12
Elements in descending order:
12 4 2 0
Example 3:Write a program to remove all odd elements from vector object
#include<iostream>
#include<vector>
using namespace std;
main()
{
vector<int> e;
int n,ele;
cout<<"\nEnter number of elements\n";
cin>>n;
cout<<"\nEnter elements\n";
for (int x=0;x<n;x++) {
cin>>ele;
e.push_back(ele);
}
Output:
Enter number of elements
5
Enter elements
4 7 3 8 2
Vector elements after erasing all odd elements
482
6.5 LISTS
The list is a frequently used feature. It allows a bi-directional linear list. Element can be
inserted or deleted at both the ends. The elements in the list can be accessed sequentially. Iterators
are used for accessing individual elements of the list.
Function Task
#include<iostream>
#include<list>
using namespace std;
void show( list <int> &l) {
list<int> :: iterator it;
for(it = l.begin(); it != l.end(); ++it)
cout<<*it<<' ';
}
main() {
list<int> e;
e.push_back(5);
e.push_front(8);
e.push_back(8);
e.push_front(2);
e.push_back(1);
e.push_front(11);
cout<<"\nNumbers are:\n";
show(e);
list<int> :: iterator it;
it =e.begin();
e.insert(it,1);
it =e.end();
e.insert(it,10);
cout<<"\nAfter inserting elements at begin and end: "<<"\n";
show(e);
e.pop_back();
e.pop_front();
cout<<"\nAfter poping elements at begin and end: "<<"\n";
show(e);
Output:
Numbers are:
11 2 8 5 8 1
After inserting elements at begin and end:
1 11 2 8 5 8 1 10
After poping elements at begin and end:
11 2 8 5 8 1
After erasing 1st and element 8 inthe list
251
clearing all elements
Now list is empty
Example 2:Program to display the elements of list object in ascending and descending orders
using iterators(use sort() and reverse() methods)
#include<iostream>
#include<algorithm>
#include<list>
using namespace std;
cout<<"\nEnter elements\n";
for (int x=0;x<n;x++)
{
cin>>ele;
e.push_back(ele);
}
Example 3:Program to copy elements of one list object to another object. Display the contents
of both the objects.
#include<iostream>
#include<list>
using namespace std;
int main()
{
list <int> listX,listY;
listX.push_back(23);
listX.push_back(19);
listX.push_back(5);
listX.push_back(15);
listX.push_back(25);
listX.push_back(20);
listY=listX;
Output:
Elements of listX:23 19 5 15 25 20
Elements of listY:23 19 5 15 25 20
In the above program, listX and listY are two objects of the list container. The listX is
initialized with six integer elements using the push_back() functions. The statement listY = listX
copies elements of the listX object to the listY object.
Example 4:Program to merge two lists and display the merged list.
#include<iostream>
#include<list>
using namespace std;
int main()
{
list <int> listX,listY;
listX.push_back(23);
listX.push_back(19);
listX.push_back(5);
listY.push_back(15);
listY.push_back(25);
listY.push_back(20);
listX.merge(listY);
cout<<"\n Merged list:" ;
show(listX);
}
Output:
Elements of listX:23 19 5
Elements of listY:15 25 20
Merged list:15 23 19 5 25 20
In the above program, the objects listX and listY are initialized with three objects each with
the function push_back(). The merge() function merges the elements of two list objects into one.
The elements are merged in the calling object.
Thus, in this program, listX calls the function, and listY is sent as an argument. The listX
contains its own elements and the elements of listY. In the output, the contents of objects listX and
listY are displayed.
6.6 Maps
A map is a series of pairs of key names and values associated with it as per figure.Access of
data values depends on the key, and it is very quick. We should specify the key to get the
corresponding value.
Function Task
#include<iostream>
#include<map>
#include<string>
main()
{
string item_name;
int codeno;
map<string,int> item;
cout<<"Enter item name and code no number for 2 items: \n";
{
cin>>item_name;
cin>>codeno;
item[item_name]=codeno;
}
item["PC"]=2510;
item.insert(pair<string,int> ("printer",2211));
cout<<"\nSize of map:"<<item.size();
Output:
Enter item name and code no number for 2 items:
mouse 121
keyboard 345
Size of map:4
List of item name and code numbersPC 2510
keyboard 345
mouse 121
printer 2211
Function Use
#include<iostream>
#include<deque>
using namespace std;
void show(deque<int> &q) {
deque<int> :: iterator it;
for(it = q.begin(); it != q.end(); ++it)
cout<<*it<<' ';
}
main()
{
deque<int> q;
q.push_back(5);
q.push_front(8);
q.push_back(9);
q.push_front(2);
q.push_back(1);
q.push_front(11);
cout<<"\nThe elements are : "<<"\n";
for(int i=0;i<q.size();i++)
cout<<q[i]<<" ";
deque <int>:: iterator it;
it =q.begin();
q.insert(it,12);
it =q.end();
q.insert(it,10);
cout<<"\nAfter inserting elements at begin and end: "<<"\n";
show(q);
Output: