std::tr1::unordered_map is ordered instead - c++

I'd like to have an unordered_map which contains the occurrences of each key; the problem is that, when I print myMap, it's ordered instead. I know it'd be better to use C++11, but I cannot for some reasons I'm not going to explain.
#include <iostream>
#include <tr1/unordered_map>
using namespace std;
using std::tr1::unordered_map;
main () {
unordered_map<int,int> myMap;
int counter, key;
cin>>counter;
for (int i=0; i<counter; i++) {
cin>>key; // Read key from keyboard
if (myMap.find(key) == myMap.end()) // If key is not already present in myMap
myMap[key] = 1; // Insert the new key with 1 occurrence
else
myMap[key]++; // Increment the current key occurrence
}
for (unordered_map<int,int>::const_iterator it = myMap.begin(); it != myMap.end(); ++it)
cout << "[" << it->first << "," << it->second << "] " << endl;
}

Related

How to print out a map with different types [duplicate]

I am writing a program that reads team names from a file and divides them into groups. Each group of size 4. I am using a:
map<int, set<string> > groups
Assume the team names to be countries names.
Now after entering all the team names into the resp. groups I want to print the contents of each group and this is where I am getting stuck.
Here is the full working code, I have written so far.
#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
void form_groups(vector<string>);
int main(){
srand(unsigned(time(NULL)));
string team_name;
vector<string> teams;
while (cin >> team_name)
{
teams.push_back(team_name);
}
random_shuffle(teams.begin(), teams.end());
form_groups(teams);
}
void form_groups(vector<string> teams)
{
map<int, set<string> > groups;
map<int, set<string> >::iterator it;
string curr_item;
int curr_group = 1;
int count = 0;
for(int i = 0; i < teams.size(); i++)
{
curr_item = teams.at(i);
count++;
if(count == 4)
{
curr_group += 1;
count = 0;
}
groups[curr_group].insert(curr_item);
}
cout << curr_group << endl;
for(it = groups.begin(); it != groups.end(); ++it)
{
}
}
Your approach is fine. By using map<int, set<string> >::iterator it you can access a the given <key,value> pair with it->first and it->second. Since set<string> is a standard container itself you can use an set<string>::iterator to traverse through the elements:
map<int, set<string> >::iterator map_it;
set<string>::iterator set_it
for(map_it = groups.begin(); map_it != groups.end(); ++map_it){
cout << "Group " << it->first << ": ";
for(set_it = map_it->second.begin(); set_it != map_it->second.end(); ++set_it)
cout << *set_it << " ";
cout << endl;
}
I think it is the iteration over the groups map that is your difficulty. Example of iterating over a map:
for (it = groups.begin(); it != groups.end(); it++)
{
// 'it->first' is the 'int' of the map entry (the key)
//
cout << "Group " << it->first << "\n";
// 'it->second' is the 'set<string>' of the map entry (the value)
//
for (set<string>::iterator name_it = it->second.begin();
name_it != it->second.end();
name_it++)
{
cout << " " << *name_it << "\n";
}
}
While iterating over a std::map<..>, it->first would give you the key, and it->second would give you the corresponding value.
You would need something like this to iterate over the map:
for(it = groups.begin(); it != groups.end(); ++it)
{
cout<<"For group: "<<it->first<<": {"; //it->first gives you the key of the map.
//it->second is the value -- the set. Iterate over it.
for (set<string>::iterator it2=it->second.begin(); it2!=it->second.end(); it2++)
cout<<*it2<<endl;
cout<<"}\n";
}

printing a value of map which has two string as key and vector as value

I have a map which has two string as key and one vector as value
how can i print the value of map.
Below is my approach which is bad Can Someone help me thanks in advance
NOTE : i want to print by key not iterating on vector
int main()
{
vector<string>value;
std::map<std::pair<string,string> ,vector<string>> myMap;
string input1,input2,MyvectorValue;
for(int i=0;i<5;++i)
{
cin>>input1;
cin>>input2;
cin>>MyvectorValue;
myMap[std::make_pair(input1,input2)].push_back(MyvectorValue);
}
int j=0;
for( auto it = myMap.begin(); it != myMap.end(); ++it )
{
std::vector<std::string>& value = it->second.at(j++);
cout<<value // This is bad
//how can i print all map value ??
}
}
The value of the map is a vector, assuming you can use C++11, the following code would do what you need.
#include <string>
#include <iostream>
#include <map>
#include <utility>
#include <vector>
int main()
{
std::vector< std::string >value;
std::map< std::pair<std::string , std::string> , std::vector<std::string> > myMap;
std::string input1,input2,MyvectorValue;
for(int i=0;i<5;++i)
{
std::cin>>input1;
std::cin>>input2;
std::cin>>MyvectorValue;
myMap[std::make_pair(input1,input2)].push_back(MyvectorValue);
}
//If you have a particular key (string1, string2), and want to print the values for that specific key...
auto particularKey = std::make_pair("stringA", "stringB");
for(auto val : myMap[particularKey])
std::cout << val << " ";
std::cout << std::endl;
// If you want to iterate through all keys of your map
for(auto &elem : myMap)
{
std::cout << "for the pair with key (" << elem.first.first << "," << elem.first.second << "), the value is the following vector" << std::endl;
for(auto s : elem.second)
{
std::cout << s << " ";
}
std::cout << std::endl << std::endl;
}
return 0;
}
You can print the keys by accessing the pair and then using first and second to get the first and second member of the pair respectively.
You can also print the values, by accessing the vectors and iterating over them, printing every string separately.
for(auto& element : myMap)
{
std::cout << "Key: {" << element.first.first << ", " << element.first.second << "}\n";
std::cout << "Value is a vector with the following strings: \n";
for(auto& str: element.second)
std::cout << str << std::endl;
}
If you want to print by key not iterating on vector , then you may declare map as "std::map,string> myMap". Then, you can do following modification to your code as given below.
int main() {
vector<string>value;
std::map<std::pair<string,string>,string> myMap;
string input1,input2,MyvectorValue;
for(int i=0; i<5; ++i) {
cin>>input1;
cin>>input2;
cin>>MyvectorValue;
myMap[std::make_pair(input1,input2)]+=MyvectorValue;
myMap[std::make_pair(input1,input2)]+= " ";
}
for( auto it = myMap.begin(); it != myMap.end(); ++it ) {
std::string& value = it->second;
cout<<value<<endl;
}
}

map iterator not dereferencable

I am getting compile error "map/set" iterator not dereferencable". What is going on here?
#include<iostream>
#include<map>
using namespace std;
int main(){
map<int, int> m;
map<int, int>::iterator itr=m.begin();
itr->first = 0;
itr->second = 0;
cout << itr->first << " " << itr->second;
return 0;
}
The map is empty, so m.begin() is equal to the past-the-end iterator and is therefore invalid.
You first have to insert elements somehow (you can also do that implicitly by using operator[]) to make it useful.
Also, you cannot modify the key of an element like this. You would have to remove (erase) the element from the map and insert a new one with the new key.
Here's an example about that:
#include<iostream>
#include<map>
using namespace std;
int main(){
map<int, int> m;
// insert element by map::insert
m.insert(make_pair(3, 3));
// insert element by map::operator[]
m[5] = 5;
std::cout << "increased values by one" << std::endl;
for(map<int, int>::iterator it = m.begin(); it != m.end(); ++it)
{
it->second += 1;
cout << it->first << " " << it->second << std::endl;
}
// replace an element:
map<int, int>::iterator thing = m.find(3);
int value = thing->second;
m.erase(thing);
m[4] = value;
std::cout << "replaced an element and inserted with different key" << std::endl;
for(map<int, int>::iterator it = m.begin(); it != m.end(); ++it)
{
cout << it->first << " " << it->second << std::endl;
}
return 0;
}
Your map's empty! What your iterator is pointing to is undefined.
What you wanted to do is
int main(){
map<int, int> m;
m[0] = 0;
map<int, int>::iterator itr=m.begin();
cout << itr->first << " " << itr->second;
return 0;
}
Here you have not assign any value. and you can not change the key of itr->first of it. It can be read only. But you can edit itr->second.
map<int, int> m;
m[10]=0;
map<int, int>::iterator itr=m.begin();
itr->second=10;
cout << itr->first << " " << itr->second;

Print multimap<string, vector<string>>?

I am trying to display the contents of a multimap with a string and a vector as key and value, respectively. I run into problems when I try to dislpay the contents of the vector (value in multimap). What I have done so far is:
multimap<string, vector<string> > someMultimap;
vector<string> someVector;
someVector.push_back("test");
someMultimap.insert(pair<string, vector<string> >("KEY", someVector));
//So for it works fine...
multimap <string, vector<string> >::iterator it;
for (it = someMultimap.begin(); it != someMultimap.end(); ++it)
{
cout << it->first << endl << endl << it->second << endl << endl;
^^^^^^^^^^
this is the problem, canĀ“t do this with a vector(?)
}
Does anyone have a suggestion for solving the problem?
You can add a second loop for the vector.
multimap <string, vector<string> >::const_iterator it;
for (it = someMultimap.begin(); it != someMultimap.end(); ++it)
{
cout << it->first << endl ;
vector<string>::const_iterator itVec;
for (itVec = it->second.begin(); itVec != it->second.end(); ++itVec)
{
cout << *itVec <<" ";
}
cout<<endl;
}
If you don't plan to modify any value you can make your iterators const
Use std::copy to output the vector's contents with a single function:
#include <iterator>
#include <algorithm>
#include <iostream>
//..
using namespace std;
for (it = someMultimap.begin(); it != someMultimap.end(); ++it)
{
cout << it->first << "\n\n";
copy(it->second.begin(), it->second.end(), ostream_iterator<string>(cout, " "));
cout << "\n\n";
}
Loop through the vector and print:
cout << it->first << endl << endl;
for (vector<string>::iterator j(it->second.begin()); j != it->second.end(); ++j)
cout << *j << " ";
cout << endl << endl;
Also, don't use std::endl, it flushes on each call which can hinder performance.
Well, you can define what it means to send a std::vector to a std::ostream.
Here's an example of one way to do it:
template<typename T>
std::ostream& operator <<(std::ostream& stream, std::vector<T> const& v) {
for (auto&& e : v) {
stream << e << ' ';
}
return stream;
}

Printing contents of sets included in a map

I am writing a program that reads team names from a file and divides them into groups. Each group of size 4. I am using a:
map<int, set<string> > groups
Assume the team names to be countries names.
Now after entering all the team names into the resp. groups I want to print the contents of each group and this is where I am getting stuck.
Here is the full working code, I have written so far.
#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
void form_groups(vector<string>);
int main(){
srand(unsigned(time(NULL)));
string team_name;
vector<string> teams;
while (cin >> team_name)
{
teams.push_back(team_name);
}
random_shuffle(teams.begin(), teams.end());
form_groups(teams);
}
void form_groups(vector<string> teams)
{
map<int, set<string> > groups;
map<int, set<string> >::iterator it;
string curr_item;
int curr_group = 1;
int count = 0;
for(int i = 0; i < teams.size(); i++)
{
curr_item = teams.at(i);
count++;
if(count == 4)
{
curr_group += 1;
count = 0;
}
groups[curr_group].insert(curr_item);
}
cout << curr_group << endl;
for(it = groups.begin(); it != groups.end(); ++it)
{
}
}
Your approach is fine. By using map<int, set<string> >::iterator it you can access a the given <key,value> pair with it->first and it->second. Since set<string> is a standard container itself you can use an set<string>::iterator to traverse through the elements:
map<int, set<string> >::iterator map_it;
set<string>::iterator set_it
for(map_it = groups.begin(); map_it != groups.end(); ++map_it){
cout << "Group " << it->first << ": ";
for(set_it = map_it->second.begin(); set_it != map_it->second.end(); ++set_it)
cout << *set_it << " ";
cout << endl;
}
I think it is the iteration over the groups map that is your difficulty. Example of iterating over a map:
for (it = groups.begin(); it != groups.end(); it++)
{
// 'it->first' is the 'int' of the map entry (the key)
//
cout << "Group " << it->first << "\n";
// 'it->second' is the 'set<string>' of the map entry (the value)
//
for (set<string>::iterator name_it = it->second.begin();
name_it != it->second.end();
name_it++)
{
cout << " " << *name_it << "\n";
}
}
While iterating over a std::map<..>, it->first would give you the key, and it->second would give you the corresponding value.
You would need something like this to iterate over the map:
for(it = groups.begin(); it != groups.end(); ++it)
{
cout<<"For group: "<<it->first<<": {"; //it->first gives you the key of the map.
//it->second is the value -- the set. Iterate over it.
for (set<string>::iterator it2=it->second.begin(); it2!=it->second.end(); it2++)
cout<<*it2<<endl;
cout<<"}\n";
}