diff --git a/BinarySearch.md b/BinarySearch.md new file mode 100644 index 0000000..a153213 --- /dev/null +++ b/BinarySearch.md @@ -0,0 +1,161 @@ +# Binary Search + +*** + +
+ About Binary Search + +In computer science, **Binary Search**, also known as **half-interval search**, **logarithmic search**, or **binary chop**, is a search algorithm that finds the position of a target value within a sorted array. + +Binary search compares the target value to the middle element of the array. If they are not equal, the half in which the target cannot lie is eliminated and the search continues on the remaining half, again taking the middle element to compare to the target value, and repeating this until the target value is found. If the search ends with the remaining half being empty, the target is not in the array. + +Binary search runs in logarithmic time in the worst case, making **O(log n)** comparisons, where **n** is the number of elements in the array. Binary search is faster than linear search except for small arrays. However, the array must be sorted first to be able to apply binary search. There are specialized data structures designed for fast searching, such as hash tables, that can be searched more efficiently than binary search. However, binary search can be used to solve a wider range of problems, such as finding the next-smallest or next-largest element in the array relative to the target even if it is absent from the array. + +There are numerous variations of binary search. In particular, fractional cascading speeds up binary searches for the same value in multiple arrays. Fractional cascading efficiently solves a number of search problems in computational geometry and in numerous other fields. Exponential search extends binary search to unbounded lists. The binary search tree and B-tree data structures are based on binary search. + +
+ + +### Algorithm + +*** + +
+ Explanation + +Binary search works on sorted arrays. Binary search begins by comparing an element in the middle of the array with the target value. If the target value matches the element, its position in the array is returned. If the target value is less than the element, the search continues in the lower half of the array. If the target value is greater than the element, the search continues in the upper half of the array. By doing this, the algorithm eliminates the half in which the target value cannot lie in each iteration. + +
+ + + +Let **A** be an array, which has **n** elements and we want to search for a number **T**. The **Pseudocode** of searching for this item is given below: + +
+ Pseudocode + + function binary_search(A, n, T) is + L := 0 + R := n − 1 + while L ≤ R do + m := floor((L + R) / 2) + if A[m] < T then + L := m + 1 + else if A[m] > T then + R := m − 1 + else: + return m + return unsuccessful + +
+ +The **function** for running Binary Search over a sorted array is given below: + +
+ Function of Binary Search + +```cpp + +int BinarySearch ( int DATA[], int LB, int UB, int ITEM ) +{ + int BEG = LB, END = UB, MID; + + while( BEG <= END ) { + MID = ( int ) ( BEG + END ) / 2; + if ( ITEM < DATA[MID] ) { // ITEM < DATA[MID]. Update END value + END = MID - 1; + } + else if ( ITEM > DATA[MID] ) { // ITEM > DATA[MID]. Update BEG value + BEG = MID + 1; + } + else { + return MID; // found the item! So returning its index + } + } + return -1; // there is no such item. So returning an impossible index +} + +``` + +
+ + +
+ More about the function of Binary Search + +In this function - + +```cpp + +int DATA[] = the dataset given to us. +int LB = the lower bound of the range we want to search for. +int UB = the upper bound of the range we want to search for. +int ITEM = the item which we are searching. + +``` + +Suppose, we have a sorted array **DATA[8] = { 10, 20, 20, 20, 30, 30, 40, 50 }**. We would like to search if **40** is present in this array or not. And we want to search in the whole array. In this case, + +```cpp + +int LB = 0; +int UB = 7; +int ITEM = 40 + +``` + +Then we call the function to get the location of the item. + +```cpp + +int index = BinarySearch ( DATA[], 0, 8, 40 ); +if( index == -1 ) std::cout << "Item Not Found" << endl; +else std::cout << "Item Found at Index " << index << endl; + +``` + +``` +Output: +Item Found at Index 6 +``` + +If we set `ITEM = 25`, the output will be - `Item Not Found`. + +If we do not want to run Binary Search over the whole array but on a section of the array, we just have to set the boundary. Suppose we want to run over from index 2 to index 5 of the array, then our code will look like - + +```cpp + +int index = BinarySearch ( DATA[], 2, 5, 40 ); + +``` + +``` +Output: +Item Not Found. +``` + +This is the most simple version of Binary Search. We can also use Binary Search to find some other things too, such as - we can find **Lower Bound** and **Upper Bound** of an item, **smallest element** and **largest element** from a rotated (after sorted) array, we can also solve some other problems like **Max in a hill** or **Min in a canyon**. We will be exploring them in the further part. + +
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 5c46278..bb7b2b1 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - Dynamic Programming - BitSet - Greedy +- [Binary Search](https://definecoder.github.io/BinarySearch) - Two Pointer - Geometry - Combinatorics diff --git a/STL/PriorityQueue.md b/STL/PriorityQueue.md index 8ba26b6..3275987 100644 --- a/STL/PriorityQueue.md +++ b/STL/PriorityQueue.md @@ -20,10 +20,14 @@ This creates a priority queue nammed MyPriorityQueue of a cerrain data type. ## Operations You can do the following operation in a priority queue : -- push -- pop -- top - + _**PUSH :**_ This operation takes an input of certain data type and pushes it into your priority queue or heap. It works same as pushing something in a heap. It take logN time to do this operation. Suppose you want to push 12, 18, 8 into your priority queue. You can do that using the following code: ++ push ++ pop ++ top
+ +Now lets see the implementation + +## Implementation of the operations ++ _**PUSH :**_ This operation takes an input of certain data type and pushes it into your priority queue or heap. It works same as pushing something in a heap. It take logN time to do this operation. Suppose you want to push 12, 18, 8 into your priority queue. You can do that using the following code: ```cpp priority_queue < int > MyPQ; MyPQ.push(12); @@ -31,7 +35,7 @@ You can do the following operation in a priority queue : MyPQ.push(8); ``` This code makes a priority queue of integers named MyPQ and pushes 12, 18 and 8 into that. Then it works like a heap and so you can pop out the maximum number from the heap list in just logN time which means this 3 numbers will be stored in this sequence { 18, 12, 8 }. - + _**POP :**_ You can retrieve the maximum number from the numbers you pushed earlier using this operation. You can see the following code to see the implementation of this operation : ++ _**POP :**_ You can retrieve the maximum number from the numbers you pushed earlier using this operation. You can see the following code to see the implementation of this operation : ```cpp priority_queue < int > MyPQ; MyPQ.push(12); @@ -44,7 +48,7 @@ You can do the following operation in a priority queue : // Now the queue will be empty ``` This pop functionality works like popping from a heap. And after popping it automatically adjusts the queue in logN time. - + _**TOP :**_ This function gives us the access to the topmost element of the priority queue. If the queue is in default mode it will return the maximum element and if it is declared as the smaller version of the heap it will return the smallest number of the list. See the following code for better understanding : ++ _**TOP :**_ This function gives us the access to the topmost element of the priority queue. If the queue is in default mode it will return the maximum element and if it is declared as the smaller version of the heap it will return the smallest number of the list. See the following code for better understanding : ```cpp priority_queue < int > MyPQ; MyPQ.push(12); @@ -53,3 +57,97 @@ You can do the following operation in a priority queue : cout << MyPQ.top() << endl; // prints 18 as it is the largest among the heap ``` +*** +## Printing a Priority Queue using a custom function : +There are no library function to print a queue without popping. So, we will write a custom function of oue own to print a priority queue. We will send a copy of our priority queue in order to print it. We can pop that copy because it will not change the main Priority_queue which is inside the main function. So, Lets see the code : + ```cpp + #include + #include + + using namespace std; + + void print_priority_queue(priority_queue < int > temp) + { + cout << "Elements of the priority_queue are :: \n" ; + while ( !temp.empty() ) + { + cout << temp.top() << " "; + temp.pop(); + } + cout << '\n'; + } + + int main(){ + priority_queue < int > MyPQ; + MyPQ.push(12); + MyPQ.push(18); + MyPQ.push(8); + // After Pushing the queue will be 18, 12, 8 + print_priority_queue(MyPQ); + // printing the priority queue using custom function + // Here we are sending a copy of the queue + MyPQ.pop(); // popping 18 + MyPQ.pop(); // popping 12 + MyPQ.pop(); // popping 8 + // Now the queue will be empty + return 0; + } + ``` +### OUTPUT: + ``` + Elements of the priority_queue are :: + 18 12 8 + ``` + +## Set the Minimum Number as priority ( Minimum Number Heap ) +Sometimes your priority can be to pop the smallest number first. Which means if you want to keep your data in ascending order you need to declare the priority queue using the following code : + + ```cpp + #include + #include + + using namespace std; + + // Function to print minimum heap priority queue + void print_spcl_priority_queue(priority_queue < int , vector < int > , greater < int > > temp) + { + cout << "Elements of the priority_queue are :: \n" ; + while ( !temp.empty() ) + { + cout << temp.top() << " "; + temp.pop(); + } + cout << '\n'; + } + + int main(){ + priority_queue < int , vector < int > , greater < int > > MySpclPQ; + MySpclPQ.push(12); + MySpclPQ.push(18); + MySpclPQ.push(8); + // After Pushing the queue will be 8 , 12 , 18 + print_spcl_priority_queue(MySpclPQ); + // printing the priority queue + MySpclPQ.pop(); // popping 8 + MySpclPQ.pop(); // popping 12 + MySpclPQ.pop(); // popping 18 + // Now the queue will be empty + return 0; + } + ``` +### OUTPUT : + ``` + Elements of the minimum_heap_priority_queue are :: + 8 12 18 + ``` +Here we changed the argument of the queue printing function to _**`priority_queue < int , vector < int > , greater < int > > temp`**_ To let the function know that it is a minimum heap. + +## Functions : + +| Function | Work of the function | +|:-------------:|:------------------------------------------------------------:| +| MyPQ.empty() | Returns True is MyPQ is empty otherwise returns False | +| MyPQ.top() | Returns the most prioritized (Topmost) element of the queue | +| MyPQ.pop() | Removes the most prioritized (Topmost) element of the queue | +| MyPQ.push(x) | Pushes x into the heap | +| pq1.swap(pq2) | Swaps the values from pq1 to pq2 | diff --git a/STL/home.md b/STL/home.md index 7909d76..4c1dbcb 100644 --- a/STL/home.md +++ b/STL/home.md @@ -16,7 +16,7 @@ STL is a very powefull tool for **competitive programming**. It saves a lot of t * Multiset * Unordered Set * Unordered Multiset -- Map +- [Map](https://definecoder.github.io/STL/map) * Multimap * Unordered Map * Unordered Multimap diff --git a/STL/map.md b/STL/map.md new file mode 100644 index 0000000..10a14f4 --- /dev/null +++ b/STL/map.md @@ -0,0 +1,93 @@ +# Map in C++ + +## Introduction + +Map is one of the most powerful tools in STL. There are countless uses of maps and all of them are very useful. According to [cplusplus.com](http://www.cplusplus.com/reference/map/map/), Maps are associative containers that store elements formed by a combination of a key value and a mapped value, following a specific order. There are many things common between Set and Map. Infact some argues that **Map** is nothing but a 2D **Set**. So, without further due, lets jump into it! + +## Declaration +For using map you need to add the following header file: +```cpp +#include +``` +And the general structure of map is: +``` +map M; +``` +So, in a map, There are some elements which has a key value and a mapped value. ```No two mapped values can have same key values. key values are unique & and Key values are also sorted like set. but mapped values can be duplicate.``` For example lets declare a map of 'string as key' and 'integers as mapped value': +```cpp +map M; +``` +## Basic Operations + +Map is in a way vector of pairs where first element is a key value, which has to be unique(different for multimap we'll come to that later) and second element is mapped value. Now to be clear let's write a code: +```cpp +#include +int main() +{ + map M; + M["Shanto"] = 29; + M["Mehraj"] = 42; + M["Mugdha"] = 1; + cout << M["shanto"] << endl; +} +``` +``` +output: 29 +``` +There are several ways to initialize a map, we could also use: +```cpp +M.insert(make_pair("Shanto", 29)); +``` +Now if we want to print the whole map we can do it by iterators: +```cpp +for(auto it = M.begin(); it != M.end(); it++){ + cout << it->first << ' ' << it -> second << endl; +} +``` +``` +output: +Mehraj 42 +Mugdha 1 +Shanto 29 +``` +Now if we analyze the output we would notice that `our map is not printed in the input order rather it was printed in lexicographical order of key values`. Here, *Mehraj* is lexicographically less then *Mugdha*. That's why *Mehraj* was printed first. +|Key Value| mapped value| +|----------|------------| +|Mehraj|42| +|Mugdha|1| +|Shanto|29| + +Now what will happen if we add same key value? Lets code: +```cpp +. +. +M["Shanto"] = 30; +// now print all +``` +``` +output: +Mehraj 42 +Mugdha 1 +Shanto 30 +``` +As you see the mapped value of *Shanto* is updated but it didn't create the same key value again! + +Let's see another example, suppose we're given a sequence of numbers and we need to find the occurence of every distinct number in the sequence. For example, 1, 4, 1, 3. 1, 3, 4 is given. Here occurence of 1 is 3, 3 is 2 and 4 is also 2. We can solve this problem very easily by using map. +```cpp +int main(){ + map M; + int n; + cin >> n; + for(int i = 0; i < n; i++){ + int x; + cin >> x; + M[x]++; + } + for(auto x:M){ + cout << "occurence of "<< x.first << "is: "<< x.second << endl; + } +} +``` +See this code and try to understand what happened here by yourself! + + diff --git a/STL/pair.md b/STL/pair.md index 944d690..08ed637 100644 --- a/STL/pair.md +++ b/STL/pair.md @@ -83,6 +83,16 @@ int main() ``` **We could also sort the vectors of pairs in the increasing order of id or or name by using customized sort functions, which will be shown in the sorting part of STL** +## Pair functions: +| Function | work of function | +|-----|-----| +|**make_pair(value1, value2)**| Assigns value in pair| +|**pair1.swap(pair2)** | This function swaps the contents of one pair object with the contents of another pair object. The pairs must be of same type.| + + Now that you can make pairs so start solving some problems using pairs! +
+**problem links:** +1. [geeksforgeeks](https://practice.geeksforgeeks.org/problems/c-stl-set-2-pair/1) diff --git a/STL/queue.md b/STL/queue.md new file mode 100644 index 0000000..d985232 --- /dev/null +++ b/STL/queue.md @@ -0,0 +1,3 @@ +# QUEUE + +## INTRODUCTION : diff --git a/STL/set.md b/STL/set.md index 14780cc..de84c16 100644 --- a/STL/set.md +++ b/STL/set.md @@ -1,4 +1,4 @@ -# Set +# Set in C++ ## Introduction Set is a container which has very special for its functionality. This have some variants which are also discussed here later on. The main features of default set is : @@ -14,4 +14,672 @@ First of all you need to add the header file of set to use any functionality of After adding the header you can declare your set using this code: ```cpp set < data_type > MySet; +// For example you may declare a set of integers nemmed MyIntSet using : +set < int > MyIntSet; ``` +In the place of data_type you may use any data type like integer, double, charecter, string, pair etc. + +## Basic operations +The often used operations in set are : +- Insert +- Iterator +- Printing a set +- Find +- Erase +- Size +- Count +- Swap +- Upper and Lower Bound + +## Implementation of the basic operations in set +1. **INSERT :** Insertion is a very basic operation of set. Using this operation you can insert a new element into your set. But remember insersion will add a new element if that element was absent there before because set do not allows same element's occurance twice. So lets see the implementation : + + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + return 0; + } + ``` + Here you can see when we tried to insert 45 for the second time it was not inserted into the set. You can also insert variables which are taken from the user. You can do that using a varible. See the code below or better understanding: + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + int x; // variable to take input + int n; // how many number you want to insert + + for(int i = 0 ; i < n ; i++) + { + cin >> x; + Myset.insert(x); // inserting x into the MySet + } + + return 0; + } + ``` +2. **ITERATOR :** Iterators are used to point out an element in the set as well as any other container in STL. [You can check this link to know more about iterators](https://definecoder.github.io/STL/iterator). Iterators are very important to access any element in the set. Lets see the list of the iterators for set and the code: + + | Function | Work of the function | + |:--------------------------------------:|:-------------------------------------------------------------:| + | begin()
**MySet.begin()** | returns iterator to the **begin** of the set | + | end()
**MySet.end()** | returns iterator to the **end** of the set | + | advance()
**MySet.advance(it,x)** | _increments_ the position of the **it** by **x** | + | prev()
**MySet.prev(it,x)** | returns _decrement_ of the position of the **it** by **x** | + | next()
**MySet.next(it,x)** | returns _increment_ of the position of the **it** by **x** | + + **Implementation :** + + ```cpp + #include + #include + #include + // remember to include the header of iterator when you will use these functions + + using namespace std; + + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; // Declaring an iterator of integer set + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(17); // Inserting 17 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 17 , 23 , 45 + + cout << "The Elements of the set are : " << endl; + print_set(MySet); // Printing MySet (will be disscussed below) + cout << endl; + + it = MySet.begin(); + cout << "value of MySet.begin() is : " << *it << endl; + + it = MySet.end(); + it--; // decrementing it because end pointer does not contain any value + cout << "value of [MySet.end() - 1] is : " << *it << endl; + + it = MySet.begin(); + advance(it,2); + cout << "value of advance(MySet.begin(),2) is : " << *it << endl; + + it = MySet.begin(); + it = next(it,3); + cout << "value of next(MySet.begin(),3) is : " << *it << endl; + + it = MySet.end(); + it = prev(it,4); + cout << "value of prev(MySet.end(),4) is : " << *it << endl; + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 17 23 45 + + value of MySet.begin() is : 11 + value of [MySet.end() - 1] is : 45 + value of advance(MySet.begin(),2) is : 23 + value of next(MySet.begin(),3) is : 45 + value of prev(MySet.end(),4) is : 11 + ``` + +3. **PRINTING A SET :** Printing of a set can be done in two ways. First one is using iterator and the second one is using C++11 short cut feature. We will include both here. Lets see: + - _**Using Iterator**_ : As you know iterator is a pointer for the STL datatype or containers, It is very useful to access the elements in a set. First of all you need to declare an iterator of the type of the set that you want to work with. Then you have to iterate through the set using that iterator that you declared. Lest see the code for better understanding. + + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; + // Declaring an iterator to point to the elements of MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + cout << "The Elements of the set are : " << endl; + + for( it=MySet.begin() ; it != MySet.end() ; it++ ) + { + // Dereferencing the pointer( Iterator ) to see the value + cout << *it << " "; + } + + cout << endl ; + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 23 45 + ``` + + So, You can print or access the elemets of a set using iterator. + - _**Special Format of C++11**_ : This mathod is very easy to use and I prefer to use this type. Because, almost all the datatypes or STL containers support this type of iteration or traversal through the set or any container. Lets see the code to see the implementation : + + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + cout << "The Elements of the set are : " << endl; + + for( auto an_element : MySet ) // Taking elements from MySet to an_element ome by one + { + // Here an_element is a member of MySet + cout << an_element << " "; + } + + cout << endl ; + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 23 45 + ``` + + I prefer to use this format because it is simple and easy to use. **BUT REMEMBER THIS CAN ONLY BE USED IN C++11 OR HIGHER VERSION OF CPP** . + - **User-defined function to print a set :** Now we will write an user-defined function which will print a set on its own. As a perameter it will take the set (call by value). As it will sent a copy of the set, it won't do any change to the original set in the main function. Lets see the function's implementation: + + ```cpp + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + cout << "The Elements of the set are : " << endl; + + print_set(MySet); // Printing MySet + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 23 45 + ``` + +4. **FIND :** This function is used to search an element from the set. It returns an iterator which points to the element in the set. If the element is not present in the set it will return the ending positon (` which is called std::end() `) of the set. You can also find the distance of the element using `std::distance(start_iterator,ending_iterator)` function. So, Lets see the implementation of the concepts mentioned above : + + ```cpp + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; // Declaring an iterator of integer set + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(17); // Inserting 17 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 17 , 23 , 45 + + cout << "The Elements of the set are : " << endl; + print_set(MySet); // Printing MySet + cout << endl; + + it = MySet.find(23); // it will now point to 23 in the set + cout << *it << " is present in index no: " << distance( MySet.begin() , it ) << endl; + // You can see the value of it by using *it (This is also known as dereferencing) + // Here distance functions returns the distance between two iterators + + it = MySet.find(25); // it will now point to the end of the set as it is absent in the set + if(it == MySet.end()) { + // As 25 is not present it will point to MySet.end() + cout << "25 is not present in the set" << endl; + } + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 17 23 45 + + 23 is present in index no: 2 + 25 is not present in the set + ``` + +5. **ERASE :** This function is used to erase one perticuler element or some elements in a range in the set. So, There are **3** types of the erase function. I am includeing the codes for the **C++11**. [To see the codes for C++98 click on this link.](http://www.cplusplus.com/reference/set/set/erase/). Lets continue with the codes for C++11 and above : + - **Using constant value :** You can erase a constant value from the set using **`erase (const value_type& val);`** See the code below for better understanding : + + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + MySet.erase(23); // This will erase 23 from the set + + cout << "The Elements of the set are : " << endl; + + for( auto an_element : MySet ) // Taking elements from MySet to an_element ome by one + { + // Here an_element is a member of MySet + cout << an_element << " "; + } + + cout << endl ; + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + The Elements of the set are : + 11 45 + ``` + + This is how you can erase a constant value from the set. + - **Single Element using iterator :** We can also erase an element from the set using iterators. To do that we need to declare an iterator and then pass that iterator in the erase function which will cause deletation of that perticuler element. Lets see the code for better understanding : + + ```cpp + #include + #include + + using namespace std; + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; // Declaring Iterator for MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 23 , 45 + + it = MySet.find(23); // This will get the pointer to 23 + MySet.erase(it); // This will delete the pointed element which is 23 + + cout << "The Elements of the set are : " << endl; + + for( auto an_element : MySet ) // Taking elements from MySet to an_element ome by one + { + // Here an_element is a member of MySet + cout << an_element << " "; + } + + cout << endl ; + + return 0; + } + ``` + + **OUTPUT :** + + ``` + The Elements of the set are : + 11 45 + ``` + + - **Erasing a range of number by iterator :** You can even erase a range of numbers from set using iterator. To do that you need to pass two iterator. One is the starting iterator and another one is the ending iterator. This two iterator tells erase function the starting and ending position of the erase operation. Lets see the code for implementation. + + ```cpp + set < int > MySet; // Declaring MySet + set < int >::iterator it1, it2; + // Declaring Iterator for starting and ending position of erase function + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(17); // Inserting 17 + MySet.insert(94); // Inserting 94 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 17 , 23 , 45 , 94 + + it1 = MySet.find(17); // This will get the starting pointer to 17 + it2 = MySet.find(45); // This will get the ending pointer to 45 + it2++; // always remember to do 1 element increment for the ending iterator + //because it will remove all elements before it2 not the one that is in it2 + + MySet.erase(it1,it2); // This will delete 17 23 45 from the set + + cout << "The Elements of the set are : " << endl; + + for( auto an_element : MySet ) // Taking elements from MySet to an_element ome by one + { + // Here an_element is a member of MySet + cout << an_element << " "; + } + + cout << endl ; + ``` + + **OUTPUT :** + + ``` + The Elements of the set are : + 11 94 + ``` + +6. **SIZE :** This is very basic function for all the datatypes and containers in STL. It will return how many elements are there in the set. Lets see the code for the implementation : + + ```cpp + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(17); // Inserting 17 + MySet.insert(94); // Inserting 94 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 17 , 23 , 45 , 94 + + cout << "The size of MySet is :: " << MySet.size() << endl; + ``` + + **OUTPUT :** + + ``` + The size of MySet is :: 5 + ``` + +7. **COUNT :** This returns the number of occurance of a perticuler element in a set. As we know default set does not allows the occurance of the same element more than once, so the count will return 1 or 0 only. But in case of _**multiset**_ ( which we will discuss later) count will return how many times you insert a perticuler element into the set. Lets now see the implementation of std::count() in the standard set : + + ```cpp + set < int > MySet; // Declaring MySet + + MySet.insert(45); // Inserting 45 + MySet.insert(23); // Inserting 23 + MySet.insert(11); // Inserting 11 + MySet.insert(17); // Inserting 17 + MySet.insert(94); // Inserting 94 + MySet.insert(45); + // 45 is already in the set so nothing happens + // So, Now the set should be : 11 , 17 , 23 , 45 , 94 + + cout << "45 is present in the set " << MySet.count(45) << " times" << endl; + ``` + + **OUTPUT :** + + ``` + 45 is present in the set 1 times + ``` + +8. **SWAP :** Swap is a very simple function. It swaps the elements between two sets. Lets see the code to see the implementation : + + ```cpp + //Function to print set + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > setA, setB; // Declaring two sets + + setA.insert(1); // Inserting 1 + setA.insert(2); // Inserting 2 + setA.insert(3); // Inserting 3 + // So, Now the setB should be : 1 , 2 , 3 + + setB.insert(10); // Inserting 10 + setB.insert(20); // Inserting 20 + setB.insert(30); // Inserting 30 + setB.insert(40); // Inserting 40 + // So, Now the setB should be : 10 , 20 , 30 , 40 + + cout << "Before swapping --> \n"; + cout << "setA :: "; + print_set(setA); // Printing setA + + cout << "setB :: "; + print_set(setB); // Printing setB + + setA.swap(setB); // SWAPING between setA and setB + + cout << "\nAfter swapping --> \n"; + cout << "setA :: "; + print_set(setA); // Printing setA + + cout << "setB :: "; + print_set(setB); // Printing setB + + return 0; + } + ``` + + **OUTPUT :** + + ```cpp + Before swapping --> + setA :: 1 2 3 + setB :: 10 20 30 40 + + After swapping --> + setA :: 10 20 30 40 + setB :: 1 2 3 + ``` + +8. **UPPER AND LOWER BOUND:** +Upper and lower_bound is very important function for certain cases. Using find function you can search for an element if that element is not present in the set then std::find won't be able to find that element. But using Upper and lower bound you can find element which is strictly bigger (smallest number such that this number is bigger than a certain number ~ see the code for better understanding) than a certain number. Lets see the difference between **Upper_bound** and **lower_bound** : + - **UPPER BOUND :** Suppose you are given a set of integers, `S = { 12, 17, 27, 35, 47, 58, 93 }` Here if you want to know the **upper bound of 24**, it will be **27** which means _**`upper_bound(x) will return an iterator to the first element which is greater than x`**_. But in case of upper bound in the example mentioned above the **uppper_bound(35)** will be **47** because 47 is the first integer in the set which is greater than 35 (_not 35 as it is equal_). So, lets see the code for implementation : + + ```cpp + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; // Declaring an iterator of integer set + + MySet.insert(12); + MySet.insert(17); + MySet.insert(27); + MySet.insert(35); + MySet.insert(47); + MySet.insert(58); + MySet.insert(93); + // So, Now the set should be : 12 , 17 , 27 , 35, 47, 58, 93 + + cout << "The Elements of the set are : " << endl; + print_set(MySet); // Printing MySet + cout << endl; + + it = MySet.upper_bound(24); + cout << "value of MySet.upper_bound(24) is : " << *it << endl; + // *it will be 27 because 27 is the first number greater than 24 + + it = MySet.upper_bound(35); + cout << "value of MySet.upper_bound(35) is : " << *it << endl; + // *it will be 47 because 47 is the first number greater than 35 + // *it is not 35 because they are equal... + + return 0; + } + ``` + + **output :** + + ```cpp + The Elements of the set are : + 12 17 27 35 47 58 93 + + value of MySet.upper_bound(24) is : 27 + value of MySet.upper_bound(35) is : 47 + ``` + - **LOWER BOUND :** Suppose you are given a set of integers as like before, `S = { 12, 17, 27, 35, 47, 58, 93 }` Here if you want to know the **lower bound of 24**, it will be **27** which means _**`lower_bound(x) will return an iterator to the first element which is greater or equal to x`**_. But in case of lower bound in the example mentioned above the **lower_bound(35)** will be **35** because 35 is equal ot the argumant (_as it is equal_). So, lets see the code for implementation : + + ```cpp + void print_set (set < int > temp){ + for( auto an_element : temp ) + // Taking elements from temp set to an_element one by one + { + // Here an_element is a member of temp set + cout << an_element << " "; + } + cout << endl; + } + + int main(){ + + set < int > MySet; // Declaring MySet + set < int >::iterator it; // Declaring an iterator of integer set + + MySet.insert(12); + MySet.insert(17); + MySet.insert(27); + MySet.insert(35); + MySet.insert(47); + MySet.insert(58); + MySet.insert(93); + // So, Now the set should be : 12 , 17 , 27 , 35, 47, 58, 93 + + cout << "The Elements of the set are : " << endl; + print_set(MySet); // Printing MySet + cout << endl; + + it = MySet.lower_bound(24); + cout << "value of MySet.lower_bound(24) is : " << *it << endl; + // *it will be 27 because 27 is the first number greater or equal to 24 + + it = MySet.lower_bound(35); + cout << "value of MySet.lower_bound(35) is : " << *it << endl; + // *it will be 35 because 35 is equal to the argumant + // *it is will be 47 in case of upper bound + + return 0; + } + ``` + + **output :** + + ```cpp + The Elements of the set are : + 12 17 27 35 47 58 93 + + value of MySet.lower_bound(24) is : 27 + value of MySet.lower_bound(35) is : 35 + ``` + Hope that you are clear with the basic functons of a set. diff --git a/STL/stack.md b/STL/stack.md index 3aa4405..f9afb64 100644 --- a/STL/stack.md +++ b/STL/stack.md @@ -1,20 +1,116 @@ -# STACK +# **STACK** -## Introduction: +## **Introduction:** Stack is a type of container adaptor. It is just like a pile of plates kept on top of each other. we can do 2 things with a pile of plates: -- put a new plate on top -- remove the top plate -Such an arrangement is called Last In First Out(LIFO) which is not possible with Linked list and array. Stack is specifically designed to operate in a LIFO context, where elements are inserted and extracted only from one end of the container. + - put a new plate on top + - remove the top plate + +Such an arrangement is called Last In First Out(LIFO) which is not possible with Linked list and array. Stack is specifically designed to operate in a LIFO context, where a new element is added at one end called the 'top' of the stack and an element is removed from the same end only. -## Header File: +## **Header File:** we can use `#include ` to access all the library functions of stack. -## Declaration: +## **Declaration:** Genaral syntax to declare a stack is : `stack < datatype > MyStack;`. we can use any kind of datatype, stracture, container in a stack. Example : ```cpp -stack < int > MyStack; -stack < char > MyStack; -stack < vector < string > > MyStack; + stack < int > MyStack; + stack < char > MyStack; + stack < vector < string > > MyStack; ``` +## **functions:** +There are mainly four functions which are hugely used in stack. They are: + - push() + - pop() + - top() + - empty() + +#### push(): +push() function is used to input a data in the stack. This function always adds a new data on the top of the container and increases the size of the stack by one. Example: +```cpp + stack < int > MyStack; + MyStack.push(5); + MyStack.push(15); + MyStack.push(63); +``` +In this code, we have inputed some data in "MyStack". After pushing some datas the stack will be {5, 15, 63}. As '63' is the last data we have inserted, so it is on the top of the stack. + +#### pop(): +pop() is the opposite of the push() function. It removes the last data inserted in the stack. It decreases the size of the stack by one.The items are popped in the reversed order in which they are pushed. +```cpp + stack < int > MyStack; + MyStack.push(5); + MyStack.push(15); + MyStack.push(63); + //we have pushed 5, 15, 63 in the stack, the stack is{5, 15, 63} now + MyStack.pop(); //popping 63 from the stack, the stack is {5, 15} now + MyStack.pop(); //popping 15 from the stack, the stack is {5} now + MyStack.pop(); //popping 5 from the stack, the stack is empty now +``` +pop() function always deletes the data in the reversed order it was pushed. As we pushed 63 at the last it was popped at first. + +#### top(): +top() function always returns a reference to the top element(the newest) of the stack. Let's see the code: +```cpp + stack < int > MyStack; + MyStack.push(5); + MyStack.push(15); + MyStack.push(63); + cout << MyStack.top() << "\n"; +``` +`OUTPUT : 63` + +In this code '63' is on the top of the stack, so top() function will return '63'. + +#### empty(): +empty() function is used to check if the stack container is empty or not. If the stack is **empty** it returns **TRUE**. Otherwise, if the container has **at least one element** it returns **FALSE**. Let's see the example: +```cpp + stack < int > MyStack; + MyStack.push(5); //pushing an element in the stack + if(MyStack.empty() != 1) + cout << "EMPTY\n"; //if empty() funtion returns false it'll print "EMPTY" + else + cout << "FILLED\d" //if empty() funtion returns true it'll print "FILLED" +``` +`OUTPUT : FILLED` + +In this code we gave an input in MyStack, so the empty() function returned 1. As a result we got "FILLED" as an output. + +Let's see another code: +```cpp + stack < int > MyStack; + MyStack.push(5); + MyStack.push(15); + MyStack.push(63); + //the stack is {5, 15, 63} now + while(MyStack.empty() != 1){ //the loop runs untill empty() function returns 1 + cout << MyStack.top() <<" "; //prints the last element of the stack + MyStack.pop(); //decreasing the size of the stack by removing the last element + } +``` +`OUTPUT : 5 15 63` + +In this code we have firstly inputed 5, 15, 63. Then we have run a while loop. If empty() function returns 0, the loop will break. In the loop we have printed the top element everytime and also removed it from the stack. As a result the loop will run for 3 times. On the third time the last element 5 will be removed ans our stack will become empty. We know that when a stack becomes empty the empty() function will return FALSE. So the loop breaks. + +Let's see all the functions used in stack at a glance: + +|function |description| +|:-- |:-- | +|push |Insert element| +|pop |Remove top element| +|top |Access next element| +|empty |Test whether container is empty| +|size |Access next element| +|swap |Swap contents| + + +Time complexity of all above functions is O(1). + +So these were the basic concepts of stack. We must need to solve stack related problems. **Some problem links are given below:** + +- [*UVA 514*](https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=455) +- [*UVA 1062*](https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=3503) +- [*Codeforces 5C*](https://codeforces.com/contest/5/problem/C) + +Happy coding<3 diff --git a/STL/string.md b/STL/string.md index 2e2b842..af599c9 100644 --- a/STL/string.md +++ b/STL/string.md @@ -30,16 +30,19 @@ You can also check which string is lexicographically greater using **` strA > st ## String Functions : -| Function | Work of the function | -|:-----------------------:|:------------------------------------------------------------------------------:| -| MyString.size() | Returns The size of the string | -| str1.swap(str2) | Swaps the value of str1 and str2 | -| MyString.insert(x,s) | Inserts s in the xth index of MyString | -| MySrting.find(s) | returns initial index of first occurrence of the s in MyString else returns -1 | -| MySrting.rfind(s) | returns initial index of last occurrence of the s in MyString else returns -1 | -| MyString.replace(i,j,s) | Replaces j characters from ith index of MyString with new string s | -| stoi(MyString) | Returns the integer converted form of MyString | -| MyString.substr(i,k) | Returns a substing of length k from ith index of MyString | -| MyString.erase(i) | Erases every element from ith index to the end of MyString | -| MyString.clear() | Erases every element in MyStirng | -| MyString.empty() | Returns True if MyString is empty else return false | +| Function | Work of the function | +|-----------------------------|--------------------------------------------------------------------------------| +| **MyString.size()** | Returns The size of the string | +| **str1.swap(str2)** | Swaps the value of str1 and str2 | +| **MyString.insert(x,s)** | Inserts s in the xth index of MyString | +| **MySrting.find(s)** | Returns initial index of first occurrence of the s in MyString else returns -1 | +| **MySrting.rfind(s)** | Returns initial index of last occurrence of the s in MyString else returns -1 | +| **MyString.replace(i,j,s)** | Replaces j characters from ith index of MyString with new string s | +| **stoi(MyString)** | Returns the integer converted form of MyString | +| **MyString.substr(i,k)** | Returns a substing of length k from ith index of MyString | +| **MyString.erase(i)** | Erases every element from ith index to the end of MyString | +| **MyString.clear()** | Erases every element in MyStirng | +| **MyString.empty()** | Returns True if MyString is empty else return false | + +*** + diff --git a/STL/vector.md b/STL/vector.md index bd40048..d18df1a 100644 --- a/STL/vector.md +++ b/STL/vector.md @@ -1,45 +1,409 @@ # Vector + ## Introduction -Vector is one of the most powerful Data Type in ***C++ programming language*** and very much helpful for competitive programmers. The concept of vector is almost same as C programming language’s ***Array***. However, in C++, we call the vector ***“A Container”***. A container can contain everything such as *`integers, doubles, characters, bools, strings, structures`* and a vector can contain *`some vectors`* too. But the most important feature of vector is –***“Its memory is allocated dynamically.”*** We can change its length at any time and you can perform many operations that is not possible for C language’s array. We will see and learn all of these things gradually in a proper way. -
-
+ +Vector is one of the most powerful Data Type in ***C++ programming language*** and very much helpful for competitive programmers. The concept of vector is almost same as C programming language’s ***Array***. However, in C++, we call the vector ***“A Container”***. As a container, a vector can contain everything such as *`integers, doubles, characters, bools, strings, structures`* and a vector can contain *`some vectors`* too. But the most important feature of vector is –***“Its memory is allocated dynamically.”*** We can change its length at any time and you can perform many operations that is not possible for C language’s array. We will see and learn all of these things gradually in a proper way. + +*** + +### Why should we learn vector? +- We can change the size of a vector at any time +- We can delete any element at any time +- We can insert new elements at any place +- We can set all the value of all elements to an specific value without using loops +- We can copy one vector to another without using loops +- And so many things we can perform using vector which is not possible using traditional array + +*** + ## Header File -We have to include an extra header file to use this data type. That is-
-`#include `
-Under this header file, we can access all the library functions that can be used for vector data type. -
-
+ +We have to include an extra header file to use this data type. That is- `#include `. Under this header file, we can access all the library functions that can be used for vector data type. + ## Declaration and initialization of a vector -We can declare a vector in several ways. Let us see them one by one and understand their differences gradually. - - `vector < Datatype > MyVector;`
-Using this format, we can declare a vector. Now we can see that the size of the vector is not mentioned here. That means **“we have not allocated any memory for this vector.”** In this case if we want to add any value (of the datatype mentioned inside), we have to use a library function `push_back()`. For example, if we want to store 55, 72, 89 and 100 into an integer vector, we have to perform these: -```cpp - vector < int > v; - v.push_back(55); - v.push_back(72); - v.push_back(89); - v.push_back(100); -``` -Alternatively, we can write them also in a single line using commas, like this- -```cpp - vector < int > v; - v.push_back(55), v.push_back(72), v.push_back(89), v.push_back(100); -``` -The size of vector `v` will be as much element we insert into the vector using `push_back()` function. - - `vector < Datatype > MyVector(n);` where n = size of the vector.
-Thus we can initially allocate the memory needed for our vector like this. This method will give us two extra benefit: - - This will set the values of all index to 0 automatically. - - We can now access any index form 0 to size-1 inclusively by
`“MyVector[i]”`; where i = index.
-But still we can change the size of the vector at any time. Besides, we can also store more than n elements into the vector (if needed). Using `push_back()`, we can add elements from index n to maximum size. - -Suppose, we are declaring a vector of length 3 and store 3 values into the vector. we have to do it like- + +We can declare a vector in several ways. Let us see some of them at a glance and then move forward. + +- Type-01 - ***Creating an empty Vector*** + + ```c++ + vector < int > v; + ``` + +- Type-02 - ***Specifying size and initializing all values*** + - there are two criterias + - 1 + ```cpp + int n = 7; + vector < int > v(n); + + // This sets all elements to 0 automatically + // Print the vector just to be made sure + cout << "v = "; + for(int x : v) { + cout << x << " "; + } + cout << endl; + ``` + + Output: + 0 0 0 0 0 0 0 + + - This sets all elements to 0 automatically. + + - 2 + + ```cpp + int n = 7; + vector < int > v(n, 10); //The 7 elements of the vector is now 10 + + // Print the vector just to be made sure + cout << "v = "; + for(int x : v) + cout << x << " "; + cout << endl; + ``` + + Output: + 10 10 10 10 10 10 10 + + +- Type-03 - ***Initializing like arrays*** + - We can do it in 2 different styles + - Style-A + + ```cpp + vector < char > v {'d', 'e', 'f', 'i', 'n', 'e', 'c', 'o', 'd', 'e', 'r'}; + + // Print the vector just to be made sure + cout << "v = "; + for(char x : v) { + cout << x; + } + cout << endl; + ``` + + Output: + definecoder + + + - Style-B - We can use an equal sign too + + ```cpp + vector < double > v = {'d', 'e', 'f', 'i', 'n', 'e', 'c', 'o', 'd', 'e', 'r'}; + + // Print the vector just to be made sure + cout << "v = "; + for(char x : v) + cout << x; + cout << endl; + ``` + + Output: + definecoder + + +- Type-04 - ***Initializing from an array*** + ```cpp + int arr[] = {10, 20, 30}; + int n = sizeof(arr) / sizeof(arr[0]); + vector < int > v(arr, arr + n); + + // Print the vector just to be made sure + cout << "v = "; + for(int x : v) + cout << x << " "; + cout << endl; + ``` + + Output: + 10 20 30 + + +- Type-05 - ***Initializing from another vector*** + ```cpp + vector < int > motherVector {8, 4, 2, 0, 1}; + vector < int > v(motherVector.begin(), motherVector.end()); + + // Print the vector just to be made sure + cout << "v = "; + for(int x : v) + cout << x << " "; + cout << endl; + ``` + + Output: + 8 4 2 0 1 + + +*** + +### What operations can we make with an empty vector? + +- We can push elements into it using `push_back()` function. The syntax is like `VariableName.push_back(value)`. We can push as much elements as we need (but within the range). + + ```cpp + vector < char > v; + v.push_back('d'), v.push_back('e'), v.push_back('f'); + v.push_back('i'), v.push_back('n'), v.push_back('e'); + //And so on... + + // Print the vector just to be made sure + cout << "v = "; + for(char x : v) { + cout << x; + } + cout << endl; + ``` + + Output: + define + + +- The most important thing, when we declare an empty vector, is to have in mind that after declaration, the size of the vector is 0. Then when we push elements one by one, the size of the vector gradually increases. For example, in the previous code - **`"after initialization, the size was 0. Then we pushed 6 elements into the vector. Now The size of the vector is 6."`** + +- We can check the size of the vector at any time using `size()` function. The syntax is `VariableName.size()`. Compile and run the following code to make it clear. + + ```cpp + vector < double > v; + cout << "After declaration, size = " << v.size() << endl; + v.push_back(10.5); + cout << "After adding first element, size = " << v.size() << endl; + v.push_back(13.684); + cout << "After adding one more element, size = " << v.size() << endl; + v.push_back(18.12345); + cout << "After adding one more element, size = " << v.size() << endl; + ``` + + Output: + After declaration, size = 0 + After adding first element, size = 1 + After adding one more element, size = 2 + After adding one more element, size = 3 + +- We can also assign values to the vector after declaration as shown below. + + ```cpp + vector < int > v; + v = {10, 20, 30, 40}; + ``` + +*** + +### Which things should we be aware of after declaring an emtpy vector? + +- We cannot add elements without using `push_back()` function. +- We cannot just make the following operations: + + ```cpp + vector < int > v; + v[0] = 10; + v[1] = 20; + v[2] = 30; + ``` + + or, + + ```cpp + vector < int > v; + for(int i = 0; i < 10; i++) { + cin >> v[i]; + } + ``` + +- We will get a **runtime error** as we are accessing a memory that we do not have. The question is why? The answer is quite simple - **"An empty vector does not provide any memory for its elements. When we use `push_back()` function to add new elements, it provides memory for the elements."** But if we want to add memories for some elements to our vector, we have to use `resize()` function. The syntax is `VariableName.resize(NewSize)`. **Then we can access indexs form 0 to NewSize - 1.** +- So we have to use `v.Push_back(10), v.push_back(20), v.push_back(30)` in the first one. We can handle the second one like this: + + ```cpp + vector < int > v; + for(int i = 0; i < 10; i++) { + int x; + cin >> x; + v.push_back(x); + } + ``` + +- Or we can use resize the vector and access indexs from 0 to NewSize - 1. + + ```cpp + vector < int > v; + v.resize(10); + for(int i = 0; i < 10; i++) { + cin >> v[i]; + } + ``` + +- Suppose, we have declared an empty vector and then pushed 5 elements into it. After those pushing, we can change any of those value using `VariableName[index] = value`. See the following code: + + ```cpp + vector < int > v; + v.push_back(10), v.push_back(11), v.push_back(12), v.push_back(13), v.push_back(14); + v[0] = 100; + v[1] = 200; + v[2] = 300, v[3] = 400, v[4] = 500; + ``` + +- So, the lesson is **"We cannot access an index that has no allocation in the memory."** + +*** + +### What happens when we use `resize()` function? + +- Suppose we have a vector of size 5. Now we use `resize()` function to change the size of the vector to 10. After this operation, the first elements of our vector remains the same as it was before. Besides, we get (10 - 5 =) 5 extra indexes to access. Initially these new 5 indexes will contain 0 for an integer vector! Run the code: + + ```cpp + vector < int > v{1, 2, 3, 4, 5}; + v.resize(10); + for(int x : v){ + cout << x << " "; + } + cout << endl; + ``` + + Output: + 1 2 3 4 5 0 0 0 0 0 + +- The big question in our mind is **What happens after resize if the data type is not integer!** The answer is **If the datatype is `int`, `double`, `long int` or number related anything, the value is automatically set to 0. And if the data type is `char` or `string` related something, each index will contain a `NULL` character!** + +- Now suppose, we have a vector of length 7. We resize if to length 5. Then these 5 elements remains the same. Just those last elements get deleted. + + ```cpp + vector < int > v{1, 2, 3, 4, 5, 6, 7}; + v.resize(5); + for(int x : v){ + cout << x << " "; + } + cout << endl; + ``` + Output: + 1 2 3 4 5 + +*** + +### What if we want all of the elements of our vector become 0 (for number types) or NULL (for character types) after resize? + +- Use `clear()` function before resize. The syntax of `clear()` function is `VariableName.clear()`. + + ```cpp + vector < int > v{1, 2, 3, 4, 5, 6, 7}; + v.clear(); + v.resize(10); + for(int x : v){ + cout << x << " "; + } + cout << endl; + ``` + + Output: + 0 0 0 0 0 0 0 0 0 0 + +- **`clear()` function deletes all the elements of the vector and the vector becomes empty. And when we resize an empty vector, all indexes will contain 0 (or NULL) by default.** + +*** + +## The last 4 questions explains how we are going to insert new elements to our vector under different circumstances. Now we will see a list of some functions along with a short description. + +*** + +### Important Iterator Functions + +| Function | Work of the function | +|----------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| **begin()**
`v.begin()` | Returns an iterator pointing to the first element of the vector | +| **end()**
`v.end()` | Returns an iterator pointing to the theoretical element that follows the last element in a vector | +| **rbegin()**
`v.rbegin()` | Returns a reverse iterator pointing to the last element in the vector (reverse beginning). It moves from last to first. | +| **rend()**
`v.rend()` | Returns a reverse iterator pointing to the first element in the vector (reverse end). | + +Let's see their uses through code:- + ```cpp - vector < int > v(3); - v[0] = 29, v[1] = 37, v[2] = 23; + vector < int > v {1, 2, 3, 4, 5}; + + cout << "Using begin() & end(): "; + for(auto i = v.begin(); i != v.end(); i++) { + cout << *i << " "; + } + cout << endl; + + cout << "Using rbegin() & rend(): "; + for(auto i = v.rbegin(); i != v.rend(); i++) { + cout << *i << " "; + } + cout << endl; ``` -Now if we want to add more elements, we can do it by simply using `push_back()`.
+ Output: + Using begin() & end(): 1 2 3 4 5 + Using rbegin() & rend(): 5 4 3 2 1 + +In this code, `i` is used as an iterator. We have used auto to keep it simple. If we do not want to use auto, we have to declare an iterator to vector like this - `vector < int >::iterator i` and a reverse iterator like this `vector < int >::reverse_iterator j;`. The we can use `i` in the first loop and `j` in the second loop.. Then the code will be like :- + ```cpp - v.push_back(18), v.push_back(97); + vector < int > v {1, 2, 3, 4, 5}; + vector < int >::iterator i; + vector < int >::reverse_iterator j; + + cout << "Using begin() & end(): "; + for(i = v.begin(); i != v.end(); i++) { + cout << *i << " "; + } + cout << endl; + + cout << "Using rbegin() & rend(): "; + for(j = v.rbegin(); j != v.rend(); j++) { + cout << *j << " "; + } + cout << endl; ``` -**Now the size of the vector is increased from three to five**. + +*** + +### Important Capacity Functions + +| Function | Work of the function | +|------------------------------------------------|-----------------------------------------------------------------------------------------------------| +| **size()**
`v.size()` | Returns the number of elements in the vector | +| **max_size()**
`v.max_size()` | Returns the maximum number of elements that the vetor can hold | +| **capacity()**
`v.capacity` | Returns the size of the storage space currently allocated to the vector expressed as number | +| **resize()**
`v.resize(n)` | Resizes the container so that it can contain `'n'` elements | +| **empty()**
`v.empty()` | Returns whether the container is empty | +| **shrink_to_fit()**
`v.shrink_to_fit()` | Reduces the capacity of the container to fit its size and destroys all elements beyond the capacity | +| **reserve()**
`v.reserve(n)` | Requests that the vector capacity be at least enough to contain `'n'` elements | + +*** + +### Element Access Functions + +| Function | Work of the function | +|------------------------------------------|--------------------------------------------------------------------------------------------------------| +| **reference operator [g]**
`v[g]` | Returns a reference to the element at position `'g'` in the vector | +| **at(g)**
`v.at(g)` | Returns a reference to the element at position `'g'` in the vector | +| **front()**
`v.front()` | Returns a reference to the first element in the vector | +| **back()**
`v.back()` | Returns a reference to the last element of the vector | +| **data()**
`v.data()` | Returns a direct pointer to the memory array used internally by the vector to store its owned elements | + +*** + +### Modifiers + +| Function | Work of the function | +|-------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------| +| **assign()**
`v.assign(n, x)` | It assigns new value to the vector elements by replacing old ones.
More precisely, the first n elements becomes x. | +| **push_back()**
`v.push_back(x)` | It pushes the elements (x) into the vector form the back | +| **pop_back()**
`v.pop_back()` | It removes elements from a vector from the back | +| **insert()**
`v.insert(iterator position, x)` | It inserts new elements before the element at specified position | +| **erase()**
`v.erase(iterator position)`
`v.erase(iterator first, iterator last)` | It removes elements from the specified position or specified range | +| **swap()**
`v1.swap(v2)` | It is used to swap the content of one vector with another vector of same type, size may differ | +| **clear()**
`v.clear()` | It is used to remove all the elements of the vector container | + +*** + + + + + + + + + + diff --git a/STL/vector/func-codes.md b/STL/vector/func-codes.md new file mode 100644 index 0000000..2ccdc27 --- /dev/null +++ b/STL/vector/func-codes.md @@ -0,0 +1,7 @@ +This is a new page created by `Ariful Islam Shanto` + +*** + +# Some Useful Codes To Understands The Funcitons + +//will add later...