how do I print a vector of multimaps?
for example I have a vector that looks like this:
typedef std::multimap<double,std::string> resultMap;
typedef std::vector<resultMap> vector_results;
EDIT
for(vector_results::iterator i = vector_maps.begin(); i!= vector_maps.end(); i++)
{
for(vector_results::iterator j = i->first.begin(); j!= i->second.end(); j++)
{
std::cout << j->first << " " << j->second <<std::endl;
}
}
The i variable in the outer for loop points to a resultMap, which means the type of the j variable needs to be resultMap::iterator. Rewrite your loops as
for(vector_results::const_iterator i = vector_maps.begin(); i != vector_maps.end(); ++i)
{
for(resultMap::const_iterator j = i->begin(); j != i->end(); ++j)
{
std::cout << j->first << " " << j->second << std::endl;
}
}
I changed the iterator type to const_iterator since the iterators are not modifying the container elements.
If your compiler supports C++11's range based for loops, the code can be written much more succinctly
for( auto const& i : vector_maps ) {
for( auto const& j : i ) {
std::cout << j.first << " " << j.second << std::endl;
}
}
Related
template<typename s>
void vecprint2d(const s& vec){
cout<<"{"<<endl;
for(int x = 0; x < vec.size(); x++){
cout<<"{";
for(int y = 0; y < vec[x].size() - 1;y++){
cout << vec[x][y]<<", ";
}
cout<<vec[x][vec[x].size() - 1]<<"}"<<endl;
}
cout<<"}"<<endl;
}
int main(){
vector<vector<int>> vec = {{1,2,3},{},{4,5,6}};
vecprint2d(vec);
return 0;
}
in my attempt at a function for printing a vector of vectors,
why does cout inside the inner loop cause problems, or is the problem elsewhere?
the output right now looks like:
{
{
If the inner vector's size is 0, size() - 1 will overflow and it will loop forever and/or crash. Could that be what is happening on your raspberry pi?
To avoid this, handle 0-sized vectors as well.
For example like this:
template<typename s>
void vecprint2d(const s& vec) {
cout << "{" << endl;
for (auto const& row : vec) {
cout << "{";
int i = 0;
for (auto const& val : row) {
if (i++)
cout << ", ";
cout << val;
}
cout << "}" << endl;
}
cout << "}" << endl;
}
The size() function of an empty vector will return an (unsigned) value of zero and, in your inner loop, you test y against vec[x].size() - 1. This will give a value that has 'underflowed' and thus have the maximum value that a size_t variable can hold, so the y loop will run a very large number of times! However, it will likely fail on the first loop, because trying to access any element of an empty vector is undefined behaviour.
To fix this, enclose your inner loop in an "is it empty" if block (in fact, you should do this for both loops). Here's a possible solution:
template<typename s>
void vecprint2d(const s& vec)
{
cout << "{" << endl;;
if (!vec.empty()) for (size_t x = 0; x < vec.size(); x++) {
cout << "{";
if (!vec[x].empty()) {
for (size_t y = 0; y < vec[x].size() - 1; y++) {
cout << vec[x][y] << ", ";
}
cout << vec[x][vec[x].size() - 1];
}
cout << "}" << endl;
}
cout << "}" << endl;
}
Feel free to ask for further clarification and/or explanation.
In my C++ script, I want to insert some elements of a list into a vector (from the beginning of list to a specific position "it"), and then try to add the vector at the top of the list and keeping the same order of the vector but I get unwanted additional elements in the vector.
Here is my code:
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
int main() {
std::list<int> mylist;
for (int i = 0; i < 10; i++)
mylist.push_back(i * 10);
for (std::list<int>::iterator i = mylist.begin(); i <= mylist.end(); ++i) {
std::cout << *i << ", ";
}
std::cout << std::endl;
std::advance(it, 6);
std::cout << "The 6th element in mylist is: " << *it << std::endl;
// The vector that will contain mylist elements
std::vector<int> intAdeplacer;
intAdeplacer.insert(intAdeplacer.end(), mylist.begin(), it);
std::cout << std::endl;
std::cout << "Nombre d'éléments dans le vecteur : " << intAdeplacer.size() << std::endl;
std::cout << std::endl;
// see the content of the vector
std::cout << "Le vecteur de deplacement contient : " << std::endl;
for (std::vector<int>::const_iterator i = intAdeplacer.begin();
i <= intAdeplacer.end(); ++i) {
std::cout << *i << ", ";
}
I get this output:
Le vecteur de deplacement contient :
0, 10, 20, 30, 40, 134985,
134985 is not wanted..
// Insert in front of the list the values of the vector and keeping the same order of elements in the vector
for (std::vector<int>::const_iterator i = intAdeplacer.end();
i >= intAdeplacer.begin(); --i) {
mylist.push_front(*i);
}
std::cout << std::endl;
std::cout << std::endl;
std::cout << "nouvelle composition de mylist : " << std::endl;
for (std::list<int>::const_iterator j = mylist.begin(); j != mylist.end();
++j) {
std::cout << *j << ", ";
}
std::cout << std::endl;
std::cout << std::endl;
// erasing the added elements from mylist
std::list<int>::iterator debut = mylist.begin();
std::list<int>::iterator fin = mylist.end();
std::advance(fin, 6);
mylist.erase(debut, fin);
for (std::list<int>::iterator j = mylist.begin(); j <= mylist.end(); ++j) {
std::cout << *j << ", ";
}
return 0;
}
If it is an iterator pointing at the 6th element of your list, the following insert() will insert from begin() (included) to it (excluded) into the vector:
intAdeplacer.insert(intAdeplacer.end(), mylist.begin(), it);
So you'll have only 5 elements, from 0 to 40. Unfortunately your printing loop does include the end() of the vector, which is out of range. This is why you get this strange trailing number.
Just correct your loop into:
for (auto i = intAdeplacer.begin(); i != intAdeplacer.end(); ++i) {
std::cout << *i << ", ";
}
Or consider this alternate range-for syntax:
for (auto &element: intAdeplacer) {
std::cout << element << ", ";
}
Hey I was just wondering is it possible in c++ to have a function in my program that as an input takes a vector or a vector. Here's an example what I want:
void PrintValues(const std::string& title, std::vector<std::vector<double>>& v)
{
std::cout << title << std::endl;
for(size_t line = 0; line < v.size(); ++line)
{
for(size_t val = 0; val < v[line].size(); ++val)
{
std::cout << v[line][val] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
I have two 2d vectors I want to print in this program and I want to use a call to this function to print both one is full with doubles and the other ints. Is this possible or will my ints be auto converted to doubles??
Thanks
Make your function a template
template <typename T>
void PrintValues(const std::string& title, std::vector<std::vector<T> >& v)
{
std::cout << title << std::endl;
for(size_t line = 0; line < v.size(); ++line)
{
for(size_t val = 0; val < v[line].size(); ++val)
{
std::cout << v[line][val] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
And the use:
std::vector<std::vector<int> > x;
std::vector<std::vector<double> > y;
PrintValues("Int",x);
PrintValues("Doubles",y);
I have a vector array called nVectors.
vector<int>* nVectors[21];
for (int i = 1; i <= 20; i ++) {
nVectors[i] = generateVector(i);
}
I can print all the members of a single vector, but when it comes to the vector array, I still don't know how to print all the vectors in an array.
Maybe an iterator through all the member of a vector array and print using my predefined method pvector can solve this problem? But I don't know how to iterate in gdb.
std::array<std::vector<int>*, 21> nVectors;
for(std::array<std::vector<int>*>::iterator i = nVectors.begin();
i != nVectors.end();
++i)
{
for(std::vector<int>::iterator it = (*i)->begin();
it != (*i)->end();
++it)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;
Or, in C++11:
std::vector<int>* nVectors[21];
for(auto &i : nVectors)
{
for(auto &it : i)
{
std::cout << *it << " ";
}
}
std::cout << std::endl;
typedef std::pair<int, bool> acq_pair; //edge, channel_quality
typedef std::pair<int, acq_pair> ac_pair;
typedef std::multimap<int, acq_pair> ac_map;
typedef ac_map::iterator It_acq;
int bits = acq_map.size();
std::cout << "bits = " << bits << std::endl;
std::vector<std::vector<bool> > c_flags (1 << bits);
for (i = 0; i < c_flags.size(); ++i)
{
for (j = 0; j < bits; ++j)
{
c_flags[i].push_back( (i & (1 << j)) > 0);
}
}
std::cout << "c_flags.size() = " << c_flags.size() << std::endl;
for(i = 0; i < c_flags.size(); ++i)
{
for(j = 0; j < bits; ++j)
{
std::cout << c_flags[i][j] << std::endl;
for(It_acq itc = acq_map.begin(); itc!= acq_map.end(); ++itc)
{
acq_pair it1 = itc->second;
itc->second.second = c_flags[i][j];
std::cout << itc->first << " : " << it1.first << " : " << it1.second << std::endl;
}
}
std::cout << "\n" << std::endl;
}
How can I access only one item from the multimap container at a time? I want to update only the jth value in the map, but when I iterate through the map all the bool values are changed. Is there a selective way to access the map container values?
The line itc->second.second = c_flags[i][j]; performed in a loop with itc from begin() to end() indeed performs assignment to every value of the map. If the goal was to modify only the j'th value in the map, there was no need for a loop over the entire map:
for(size_t j = 0; j < bits; ++j)
{
std::cout << c_flags[i][j] << std::endl;
It_acq itc = acq_map.begin(); // itc points at the beginning
advance(itc, j); // itc points at the j'th element
itc->second.second = c_flags[i][j]; // the assignment
for(It_acq itc = acq_map.begin(); itc!= acq_map.end(); ++itc)
{
acq_pair it1 = itc->second;
// itc->second.second = c_flags[i][j]; // no assignment here
std::cout << itc->first << " : " << it1.first << " : " << it1.second << std::endl;
}
}
If this map is used for indexed access in this manner, it may be worthwhile to consider switching to vector, though.