//
// main.cpp
// Map and Unordered Map (STL)
//
// Created by Himanshu on 23/03/22.
//
#include <iostream>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;
void printUnorderedMap (unordered_map<string, int> myMap) {
for (auto& it: myMap) {
cout<<(it.first)<<": "<<(it.second)<<" ";
}
cout<<endl;
}
void printMap (map<string, int> myMap) {
for (auto& it: myMap) {
cout<<(it.first)<<": "<<(it.second)<<" ";
}
cout<<endl;
}
int main () {
unordered_map<string, int> initUnorderedMap = { {"beta", 2}, {"gamma", 3}, {"alpha", 1} };
map<string, int> initMap = { {"beta", 2}, {"gamma", 3}, {"alpha", 1} };
unordered_map<string, int> myUnorderedMap;
map<string, int> myMap;
map<string, int>::iterator it;
//Iterating over 'unordered_map'
cout<<"initUnorderedMap elements:"<<endl;
printUnorderedMap(initUnorderedMap);
//Iterating over 'map'
cout<<endl<<"initMap elements:"<<endl;
printMap(initMap);
cout<<"Elements in the initMap (map) container are kept sorted based on their key values"<<endl;
initUnorderedMap.clear();
//size of unordered_map after clear
cout<<endl<<"Size of unordered_map after clear: "<<initUnorderedMap.size()<<endl;
initMap.clear();
//size of map after clear
cout<<endl<<"Size of map after clear: "<<initMap.size()<<endl;
myUnorderedMap.insert({"first", 30});
myUnorderedMap["second"] = 20;
myUnorderedMap["third"] = 10;
myMap.insert({"first", 10});
myMap["second"] = 20;
myMap["third"] = 30;
//Iterating over 'myUnorderedMap'
cout<<endl<<"myUnorderedMap elements:"<<endl;
printUnorderedMap(myUnorderedMap);
//Iterating over 'myMap'
cout<<endl<<"myMap elements:"<<endl;
printMap(myMap);
//Iterating over 'myUnorderedMap' after erase
myUnorderedMap.erase("second");
cout<<endl<<"myUnorderedMap elements after erase 'second': "<<endl;
printUnorderedMap(myUnorderedMap);
//Iterating over 'myMap' after erase
myMap.erase(myMap.begin());
cout<<endl<<"myMap elements after erase myMap.begin(): "<<endl;
printMap(myMap);
cout<<endl<<"Find operation on map and unordered_map:"<<endl;
if (myUnorderedMap.find("second") != myUnorderedMap.end()) {
cout<<"key 'second' is present in myUnorderedMap"<<endl;
} else {
cout<<"key 'second' is not present in myUnorderedMap"<<endl;
}
if (myMap.find("second") != myMap.end()) {
cout<<"key 'second' is present in myMap"<<endl;
} else {
cout<<"key 'second' is not present in myMap"<<endl;
}
myMap.clear();
myMap["a"] = 1;
myMap["b"] = 2;
myMap["c"] = 3;
myMap["d"] = 4;
myMap["e"] = 5;
myMap["f"] = 6;
myMap["g"] = 7;
myMap["h"] = 8;
//Iterating over 'myMap'
cout<<endl<<"myMap new elements after clear:"<<endl;
printMap(myMap);
//Iterating over 'myMap' after erase on a range
myMap.erase(myMap.find("f"), myMap.end());
cout<<endl<<"myMap elements after erasing a range of elements:"<<endl;
printMap(myMap);
//Upper bound of "c" in myMap
cout<<endl<<"(Upper bound method is available for map but not for unordered_map) Upper bound of 'c' in myMap: ";
cout<<((myMap.upper_bound("c"))->first)<<": "<<((myMap.upper_bound("c"))->second)<<endl;
//Lower bound of "c" in myMap
it = myMap.lower_bound("c");
cout<<endl<<"(Lower bound method is available for map but not for unordered_map) Lower bound of 'c' in myMap: ";
cout<<it->first<<": "<<it->second<<endl;
return 0;
}