access map in vector c++ - c++

Does anyone know how I can access map key/value when the map is in the vector?
struct ControlPointSet
{
std::map<uint32_t,uint32_t> control_points;
}
When the vector look like this:
void someMethod(const std::vector<ControlPointSet>& controlpoint_sets)
{
//run through the map vector
for(auto it = controlpoint_sets.begin(); it != controlpoint_sets.end(); it++)
{
for(int i = 0; i < it->control_points.size(); i ++)
{
std::cout << it->control_points.at(i) << std::endl;
}
}
Somehow this is not working

You cannot access a std::map's elements by index. Its at() method takes a key as input instead.
You can use an iterator:
void someMethod(const std::vector<ControlPointSet>& controlpoint_sets)
{
//run through the elements of the vector
for(auto it = controlpoint_sets.begin(); it != controlpoint_sets.end(); ++it)
{
//run through the elements of a map
for(auto cp = it->control_points.begin(); cp != it->control_points.end(); ++cp)
{
std::cout << cp->first << " " << cp->second << std::endl;
}
}
}
Or a range-based for loop:
void someMethod(const std::vector<ControlPointSet>& controlpoint_sets)
{
//run through the elements of the vector
for(const auto &cps : controlpoint_sets)
{
//run through the elements of a map
for(const auto &cp : cps.control_points)
{
std::cout << cp.first << " " << cp.second << std::endl;
}
}
}

Related

Getting strange error while trying to set up an iterator

This is probably a silly error but I can't seem to find what I have done wrong.
The error I am getting is no operator "=" matches these operands.
Here is my code...
void print_words(const map < string, int >& m1) {
map<string, int>::iterator it;
cout << "Number of non-empty words: " << m1.size() << '\n';
int count = 0;
for (it = m1.begin(); it != m1.end(); it++) {
}
}
I get the error in the for loop in the it = m1.begin() statement and I cannot go on to print out the map if I can't iterate through it.
Use a const iterator:
void print_words(const map < string, int >& m1) {
cout << "Number of non-empty words: " << m1.size() << '\n';
int count = 0;
for (map<string, int>::const_iterator it = m1.cbegin(); it != m1.cend(); it++) {
}
}
Use a const_iterator or auto.
void print_words(const map < string, int >& m1) {
cout << "Number of non-empty words: " << m1.size() << '\n';
int count = 0;
for (auto it = m1.cbegin(); it != m1.cend(); it++) {
}
}

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;
}
}

How to insert multiple String in an Array

In C++ how can I insert multiple string in an array and print it, like:
Array[] = {"One", "Two", "Three", "Four".......};
I want to print them according to their index location.
Thank you.
If you want to use raw array, should be:
std::string strArr[] = { "One","Two","Three","Four" };
for (size_t i = 0; i < sizeof(strArr) / sizeof(std::string); i++)
{
std::cout << strArr[i] << " ";
}
std::cout << std::endl;
It's better to use vector instead of raw array:
std::vector<std::string> strVec = { "One","Two","Three","Four" };
for (size_t i = 0; i < strVec.size(); i++)
{
std::cout << strVec[i] << " ";
}
std::cout << std::endl;
Another way to traverse vector is to use iterator:
for (auto itr = strVec.begin(); itr != strVec.end(); itr++)
{
std::cout << *itr << " ";
}
std::cout << std::endl;
You can use standard vector to achieve your goal.
std::vector<std::string> stringVector = {"One","Two","Three","Four"}<br/>
std::vector can also be extended after its allocated.

map/set iterator not dereferencable. Multimap container isse

I'm geting this error message map/set iterator not dereferencable When trying to get value by key in multimap. In this code I'm trying to show nonoriented graph represented by adjacency list (vector<Vertex*> vertexList)
void NonOrGraph::show() {
cout << endl;
multimap<int, int> used;
for (int i = 0; i < vertexList.size(); i++) {
if (vertexList[i]->adjMap.empty()) {
cout << vertexList[i]->index << " isolated";
} else {
for(map<Vertex*, int>::iterator it = vertexList[i]->adjMap.begin();
it != vertexList[i]->adjMap.end();
it++)
{
int from = vertexList[i]->index;
int to = it->first->index;
int weight = it->second;
used.insert(pair<int, int>(from, to));
if (used.find(to)->second != from) {
cout << from << " <--(" << weight << ")--> " << to << endl;
}
}
}
}
cout << "\n\n";
}
The problem is likely here:
if (used.find(to)->second != from) {
If to is not in used, used.find() will return used.end(), which you then dereference. It is undefined behavior to dereference the end() iterator, which in this case manifests by giving you a runtime error.
You have to check the iterator against end() first:
std::multimap<int, int>::iterator multi_it = used.find(to);
if (multi_it != used.end() && multi_it->second != from) {
// ^^^^^^^^^^^^^^^^^^^^
// now, it's safe to dereference

How to print a vector array?

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;