STL — Standard Template Library
Here we are going to discuss about some STLs that are frequently used in competitive programming. Like string, vector, pair, queue, stack, set and map.
What is STL ?
STL (Standard Template Library): STL provides a set of common classes for C++, such as containers ( Queue , Stack ) and associative arrays ( Hash tables ) , that can be used with any built-in data-type and with any user-defined data-type that supports some elementary operations (such as copying and assignment).
All STLs provide dynamic memory allocation. Vector and string have contiguous memory allocation and the rest have non-contiguous memory allocation.
So now we should see each STL one by one:-
Vector:-
This is just like an array but it has dynamic and contiguous memory allocation. This comes under the STL library vector.
Library to be included:- vector (#include<vector>)
Declaration of a vector:-
vector< data-type > vector-name;
here data-type can be any in-built data type ( char, int ,float, double ) or any user-defined data type ( classes , structures ).
The difference and similarity between vector and array:-
Declaration of an array which can store 8 integers will go as
int arr[8];
and if we want to use a vector instead of array then we just need to write
vector< int > v; ( specifying the size is optional )
Specifying the size while declaration of vector:-
vector<int > v(8);
( not specifying the size will also be fine )
vector<int > v;
( This declaration does not mean that this vector v is going to store only one integer. This is a list of integer which has a contiguous memory allocation ).
We use push_back function for inserting any element at the end of vector.
suppose we wrote the following code
vector<int> v;for(int i=0;i<8;i++){
arr[i]=i;
v.push_back(i);
}
Now this vector v has 8 integers 0,1,2,3,4,5,6,7.
Difference:
The difference between vector and array is that the size in vector is not fixed and it can be changed dynamically because vector has dynamic memory allocation while array has static memory allocation. We do not have to specify anything about the size while declaration.
Similarity:
The similarity between vector and array is that they both have contiguous memory allocation. The advantage of having contiguous memory allocation is that we can access any element in O(1) time complexity by mentioning the index of element between the square brackets with the vector-name.
Suppose we want to access 5th element in array then we will write arr[4] and this will be same in vector v[4](because of contiguous memory allocation). both vector and array will output 4 because of the above code. But we can not access in the same way in list because it has non-contiguous memory allocation. It is basically a linked list and the time complexities for all the operations are same as linked list data structure.
We can do all the operations on vectors in the same way as we do in arrays.
Some member functions which are frequently used in vector are:-
- push_back(arg):- This function pushes the element arg at the end of the vector.
- pop_back():- This function pops an element from the end of the vector.
- back():- This function returns the last element of the vector.
- front():- This function returns the first element of the vector.
- clear():- This function clears the vector.
- size():- This returns the total number of elements which are stored in the vector.
- begin():- This returns an iterator pointing to the first element of the vector.
- end():- This returns an iterator pointing to theoretical element that follows the last element.
All of the above functions have time complexities O(1).
Example:-
#include<iostream>
#include<vector>
using namespace std;int main() {
vector<int > v;
int i;
for(i=0;i<8;i++) {
v.push_back(i);
} cout<<”First element is:- “<<v.front()<<endl;
cout<<”Last element is:- “<<v.back()<<endl; cout<<”Elements in the vector are:- “<<endl;
for(i=0;i<v.size();i++) {
cout<<v[i]<<endl;
} v.pop_back();
cout<<”Last element after pop_back:- “<<v.back()<<endl; v.clear();
cout<<”Size of vector after clearing the vector:- “<<v.size(); return 0;
}Output of the above program:-First element is:- 0
Last element is:- 7
Elements in the vector are:-
0
1
2
3
4
5
6
7
Last element after pop_back:- 6
Size of vector after clearing the vector:- 0
How does a vector do dynamic and contiguous allocation?:-
When a vector is declared a block of memory is assigned to it with a fixed capacity (the maximum number of elements to be stored in that block ). As a new element is added in the vector and the size of the vector goes more than the capacity then a new block of memory is assigned with more capacity and the previous block is copied to that new block of memory and the new element is added just after that copied block and the previous block of memory is freed. This is how it maintains above two properties.
String:-
A sequence of character is called String. This also has contiguous and dynamic memory allocation and works in the same way as vector do for dynamic and contiguous memory allocation.
Library to be included:- string (#include<string>)
Declaration of a String:-
string string-name;
How do we declare a character array in C:-
char str[N+1]; ( Here N is the number of characters in the string and extra 1 for null character )
but if want to use a STL string then we will declare it as.
string str; ( Here we do not need to specify the size )
Now we can use this same as the character array but we can not use any function from string.h in c because str is an object of class string while str in character array declaration is a pointer.
For string objects comparison, assignment and concatenation is very easy and we do not have to write any function for that we can compare them in the same way we compare integers.
string s1=”abc”,s2=”cde”;s1<s2 , s1==s2 , s2≥s1 any comparison will work fine but with same string object.s1+=s2; ( This concatenation will make s1=”abccde” ).
Here are some of the member functions of string:-
- length():- This returns the size of the string.
- clear():- clears the string
- substr(pos, len):- Returns a substring starting from pos( 0-indexed ) with size len. If the requested substring extends past the end of the string, the returned substring is
[pos, size()).
Example code:-
#include<iostream>
#include<string>using namespace std;int main() {
string s=”abcdefghijklmnopqrstuvwxyz”;
cout<<”Length of the String:- “<<s.length()<<endl;
cout<<”Characters in the String:- “;
for(int i=0;i<s.length();i++) {
cout<<s[i]<<’ ‘;
}
cout<<endl;
cout<<”Substring is:- “<<s.substr(23,3)<<endl;
s.clear();
cout<<s.length(); return 0;
}Output of the above program:-Length of the String:- 26
Characters in the String:- a b c d e f g h i j k l m n o p q r s t u v w x y z
Substring is:- xyz
Queue
Queue is a linear data structure which follows FIFO ( First in first out ). That the elements will be inserted at the end and will be removed from the front.
Push and pop in queue:- Push means inserting an element and Pop means removing an element.
It has dynamic but non-contiguous memory allocation.
Library to be included:- queue(#include<queue>)
Declaration of a Queue:-
queue<data-type> queue-name;
( Here data type can be any inbuilt or user defined datatype )
Here are some member functions of queue stl:-
- size():- returns number of elements in the queue.
- front():- returns the first element in the queue.
- push(arg):- pushes arg in the queue.
- pop():- pops the first element from the queue and does not return anything.
- empty():- returns true if the queue is empty else false.
- back():- returns the last element of the queue.
Example code:-
#include<iostream>
#include<queue>
using namespace std;int main() {
queue<int> q; for(int i=0;i<4;i++) {
q.push(i);
} cout<<"Size of the queue is:- "<<q.size()<<endl; while(!q.empty()) {
cout<<"First element in the queue:- "<<q.front()<<endl;
cout<<"Last element in the queue:- "<<q.back()<<endl; q.pop(); cout<<"Element popped"<<endl;
} return 0;
}Output of the above program:-Size of the queue is:- 4
First element in the queue:- 0
Last element in the queue:- 3
Element popped
First element in the queue:- 1
Last element in the queue:- 3
Element popped
First element in the queue:- 2
Last element in the queue:- 3
Element popped
First element in the queue:- 3
Last element in the queue:- 3
Element popped
Stack:-
Stack is a data structure which follows LIFO ( Last in First out ). That the elements will be inserted at the end and will be removed from the end.
It has dynamic but non-contiguous memory allocation.
Library to be included:- stack(#include<stack>)
Declaration of a Stack:-
stack<data-type> stack-name;
( Here data type can be any inbuilt or user defined datatype )
Here are some member functions of queue stl:-
- size():- returns number of elements in the stack.
- push(arg):- pushes arg in the stack.
- pop():- pops the first element from the stack and does not return anything.
- empty():- returns true if the stack is empty else false.
- top():- returns the element which is at the top of the stack.
Example code:-
#include<iostream>
#include<stack>
using namespace std;int main() {
stack<int > st;
for(int i=0;i<4;i++) {
st.push(i);
} cout<<"Size of the stack is:- "<<st.size()<<endl; while(st.empty()==false) {
cout<<"Element at the top of the stack:- "<<st.top()<<end;
st.pop(); cout<<"Element popped"<<endl;
} return 0;
}
Output of the above program:-Size of the stack is:- 4
Element at the top of the stack:- 3
Element popped
Element at the top of the stack:- 2
Element popped
Element at the top of the stack:- 1
Element popped
Element at the top of the stack:- 0
Element popped