Set of vectors in c++ - c++

How I can get the elements in the vectors set? This is the code I have :
std::set< std::vector<int> > conjunto;
std::vector<int> v0 = std::vector<int>(3);
v0[0]=0;
v0[1]=10;
v0[2]=20;
std::cout << v0[0];
conjunto.insert(v0);
v0[0]=1;
v0[1]=11;
v0[2]=22;
conjunto.insert(v0);
std::set< std::vector<int> >::iterator it;
std::cout << conjunto.size();
for( it = conjunto.begin(); it != conjunto.end(); it++)
std::cout << *it[0] ;

The [] operator takes precedence over the * operator, so you want to change the for loop to:
for (it = conjunto.begin(); it != conjunto.end(); it++)
std::cout << (*it)[0] << std::endl;

You're close. You need to pull the vector out of the set iterator. See below.
main()
{
std::set< std::vector<int> > conjunto;
std::vector<int> v0 = std::vector<int>(3);
v0[0]=0;
v0[1]=10;
v0[2]=20;
std::cout << v0[0] << endl;
conjunto.insert(v0);
v0[0]=1;
v0[1]=11;
v0[2]=22;
conjunto.insert(v0);
std::set< std::vector<int> >::iterator it;
std::cout << "size = " << conjunto.size() << endl;
for( it = conjunto.begin(); it != conjunto.end(); it++) {
const std::vector<int>& i = (*it); // HERE we get the vector
std::cout << i[0] << endl; // NOW we output the first item.
}
Output:
$ ./a.out
0
size = 2
0
1

Now, with C++11 standart, it's easier:
set< vector<int> > conjunto;
// filling conjunto ...
for (vector<int>& v: conjunto)
cout << v[0] << endl;

std::set<std::vector<int> >::const_iterator it = cunjunto.begin();
std::set<std::vector<int> >::const_iterator itEnd = conjunto.end();
for(; it != itEnd; ++it)
{
// Here *it references the element in the set (vector)
// Therefore, declare iterators to loop the vector and print it's elements.
std::vector<int>::const_iterator it2 = (*it).begin();
std::vector<int>::const_iterator it2End = (*it).end();
for (; it2 != it2End; ++it2)
std::cout << *it2;
}

Related

Transversing through a nested map

How do I transverse through a nested map?
I want to access the value in the second nested map
int main ()
{
std::map<int, int> cool;
cool.insert(make_pair(8,9));
std::map<char, std::map<int, int> > mmap;
mmap.insert(std::make_pair('a', cool));
cout << mmap['a'][8];
std::map<char, map<int, int> >::iterator itr;
for(itr = mmap.begin(); itr != mmap.end(); itr++){
cout << itr->second << endl;
}
return 0;
}
Your itr points to a pair<char, map<int, int> >,
so its second is a map<int, int>,
so an iterator into that will do the trick:
for(map<int, int>::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2){
cout << itr2->second << endl;
}
With C++17 you can use structured binding to accomplish this:
for (auto const& [key, val] : mmap) {
for (auto const& [k, v] : val) {
std::cout << key << " " << k << " " << v << '\n';
}
}

How to print all elements in a 2D map given the 1st index

As the title says I want to print out all the elements of "group1" in this 2D map. I tried this but I just get a huge error at the for loop.
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
map<string,map<int,double> > myMap;
myMap["group1"][13] = 10.41;
myMap["group1"][15] = 31.2;
//print all elements in "group1"
for (map< string, map<int,double> >::const_iterator iter =
myMap["group1"].begin(); iter != myMap["group1"].end(); ++iter)
{
cout << iter->first << '\t' << iter->second << '\n';
}
return 0;
}
Any help would be appreciated, thanks!
The type of myMap["group1"] is map<int,double> and not map<string,map<int,double>>
Then your code would look somehow like this:
const map<int,double> &grp1map = myMap["group1"];
for (map<int,double>::const_iterator iter = grp1map.begin(); iter != grp1map.end(); ++iter)
{
cout << iter->first << '\t' << iter->second << '\n';
}
You can simplify this with auto:
auto &grp1map = myMap["group1"];
for (auto iter = grp1map.begin(); iter != grp1map.end(); ++iter)
{
cout << iter->first << '\t' << iter->second << '\n';
}
But anyway you should do it like this:
for (auto &elem : myMap["group1"] )
{
cout << elem.first << '\t' << elem.second << '\n';
}
You want an iterator to your internal map<int,double>, whereas you are trying to get and iterator to your outer map<string,map<int,double> >:
int main() {
map<string, map<int, double> > myMap;
myMap["group1"][13] = 10.41;
myMap["group1"][15] = 31.2;
//print all elements in "group1"
for (map<int, double>::const_iterator iter =
myMap["group1"].begin(); iter != myMap["group1"].end(); ++iter)
{
cout << iter->first << '\t' << iter->second << '\n';
}
return 0;
}

Different behavior observed upon doing erase(iterator) on vector and map

A simple std::vector
std::vector<int> integers;
integers.push_back(10);
integers.push_back(11);
cout << "Before: " << integers.size(); //prints 2
I tried using 3 different versions of code to erase each element one by one C++5.1 and C++14
Version 1:
for( std::vector<int>::iterator it = integers.begin() ; it != integers.end() ; )
{
cout << "\nVal: " << *it;
it = integers.erase(it);
}
cout << "\nAfter: " << integers.size();
Output: [Expected]
Before: 2
Val: 10
Val: 11
After: 0
Version 2 in C++14:
for( std::vector<int>::iterator it1, it = integers.begin() ; it != integers.end() ; )
{
cout << "\nVal: " << *it;
it1 = std::next(it);
integers.erase(it);
it = it1;
}
Output: [Unexpected]
Before: 2
Val: 10
After: 1
While for std::map, version 2 works as expected:
int main() {
std::map<int, int> m;
m.insert(make_pair(10, 11));
m.insert(make_pair(12, 13));
cout << "Before: " << m.size();
for( std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ; )
{
cout << "\nVal: " << it->first << ", " << it->second;
it1 = std::next(it);
m.erase(it);
it = it1;
}
cout << "\nAfter: " << m.size();
return 0;
}
Outputs:
Before: 2
Val: 10, 11
Val: 12, 13
After: 0
Even this works :
for( std::map<int, int>::iterator it1, it = m.begin() ; it != m.end() ; )
{
cout << "\nVal: " << it->first << ", " << it->second;
m.erase(it++);
}
Why version 2 works on std::map but not on std::vector?
The difference is that std::vector iterators are invalidated after erasing an element while for associative containers (23.2.4 Associative container)
9 The insert and emplace members shall not affect the validity of
iterators and references to the container, and the erase members
shall invalidate only iterators and references to the erased
elements.

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;

iterate over multimap <string, map <string,int> >

i want to iterate over all items in a multimap <string,map<string,int>> but just once for each Key, but i cant make it work, here is the code im using to iterate:
for(multimap <string, map <string, int> >::iterator it = myMultimap.begin(); it != myMultimap.end(); it =myMultimap.upper_bound(it->first)){
//i read that myMultimap.upper_bound(it->first) get the elements of the same key
pair< multimap <string,map <string, int> >::iterator , multimap <string,map <string, int> >::iterator > ret;
ret = myMultimap.equal_range(it->first);
for(multimap <string, map <string, int> >::iterator it2 = ret.first; it2 != ret.second; it2++){
//here i just want to print map <string , int>
cout << (*it2).second.first << endl;
cout << (*it2).second.second << endl;
}
}
when i run it i get class std::map<std::basic_string<char>, int>’ don't have a member called ‘first’ and same thing for second.second. Sorry about my english is not my mother language.
Lets make things easier for ourselves to start with
typedef std::map<std::string, int> InnerMap;
typedef std::multimap<std::string, InnerMap> StringMap;
StringMap myMultimap;
Now, that outer loop
for (StringMap::iterator it = myMultimap.begin(); it != myMultimap.end(); ++it)
{
std::cout << "[" << it->first << "]:";
for (InnerMap::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
{
std::cout << " " << it2->first << ":" << it2->second;
}
std::cout << '\n';
}
We can also, if you have C++11, make things simpler by using auto
for (auto it = myMultimap.begin(); it != myMultimap.end(); ++it)
{
std::cout << "[" << it->first << "]:";
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
{
std::cout << " " << it2->first << ":" << it2->second;
}
std::cout << '\n';
}
What we're doing:
for (StringMap::iterator it = myMultimap.begin(); it != myMultimap.end(); ++it)
This iterates across all of the std::pair<std::string /*key*/, InnerMap /*value*/> elements that actually make up the outer multimap. If you have one key twice, you'll see both entries.
it->first is the std::string key for the current multimap entry, it->second is the InnerMap value of the current entry.
for (InnerMap::iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
This iterates over the std::pair<std::string, int> InnerMap elements of the map that is the value of this multimap slot.
--- EDIT ---
Ultimately, using C++11 you could use range based for (not sure why I thought this would be messier)
// use 'auto&' so we take a reference instead of a copy.
for (auto& it : myMultimap)
{
std::cout << "[" << it.first << "]:";
for (auto it2 : it.second)
{
std::cout << " " << it2.first << ":" << it2.second;
}
std::cout << '\n';
}
Note that, in this case, we now use "." instead of "->". This is because we're actually seeing every element (std::pair<...>) in the multimap/map, rather than a simple iterator. That is, it is of type std::pair<std::string, InnerMap>& and it2 is of type std::pair<std::string, int>&.
map<string, int>::iterator in;
for(multimap <string, map <string, int> >::iterator it = myMultimap.begin(); it != myMultimap.end(); it =myMultimap.upper_bound(it->first)){
pair< multimap <string,map <string, int> >::iterator , multimap <string,map <string, int> >::iterator > ret;
ret = myMultimap.equal_range(it->first);
for(multimap <string, map <string, int> >::iterator it2 = ret.first; it2 != ret.second; it2++){
//get the map with begin() and assign it to an iterator
in = it2->second.begin();
cout << in->first << " "<< in->second << endl;
}
}