C++ map<string, vector<char> > access - c++

I've created a map of vectors that looks like this:
map<string, vector<char> > myMap;
string key = "myKey";
vector<char> myVector;
myMap[key] = myVector;
I want to be able to append 'char's' to the vector in the map but I can't figure out how to access said vector to append once the particular key/value(vector) has been created. Any suggestions? I'm iterating over char's and might be adding a lot to the vector as I go so it would be nice to have a simple way to do it. Thanks.
I would like the vector in map to be appended as I go. I don't need the original vector...I just need to return the map of key/vector's that I've created (after apending) so that I can pass it to another function. What does the * in map* > do? Is that refrencing a pointer? (I haven't gotten there in lecture yet) Also, do I need:
myMap[key]->push_back('s');
or
myMap[key].push_back('s');
??

To append:
myMap[key].push_back('c');
Or use myMap.find, but then you have to check whether you get an end iterator. operator[] returns a reference to the vector.
But this modifies the vector stored in the map, not the original one, since you've stored a copy in the map with myMap[key] = myVector;. If that's not what you want, you should rethink your design and maybe store (smart) pointers to vectors in your map.

Given you know the key:
string key = "something";
char ch = 'a'; // the character you want to append
map<string, vector<char> >::iterator itr = myMap.find(key);
if(itr != myMap.end())
{
vector<char> &v = itr->second;
v.push_back(ch);
}
you could also use the map::operator[] to access the map entry, but if the key does not exist, a new entry with that key will be created:
vector<char> &v = myMap[key]; // a map entry will be created if key does not exist
v.push_back(ch);
or simply:
myMap[key].push_back(ch);

To access the mapped value, which in your case is a vector, you just supply the key in square brackets like you did to assign the value.
So, to append 'a':
myMap[key].push_back('a');

I have an new suggestion. You can use vector<char>* instead of vector<char> in order to collect pointer of vectors in your map. For more information see the bellow code:
map<string, vector<char>* > myMap;
string key = "myKey";
vector<char>* myVector = new vector<char>();
myMap[key] = myVector;
myMap[key]->push_back('S');

Related

How to store/access multiple values of the same key in a map C++

So lets say I declare an unordered_map like this:
unordered_map<string, vector<string>> my_map;
And I have a list of values I want to store in it like this:
vector<string> vec1 = {"banana", "apple"};
vector<string> vec2 = {"banana", "banana"};
vector<string> vec3 = {"banana", "watermelon"};
if I go through and initialize each vector to the map, using the string in its 0th index as the key, like so:
my_map[vec1[0]] = vec1;
my_map[vec2[0]] = vec2;
my_map[vec3[0]] = vec3;
Would the unordered_map store all three of the vectors despite them having the same access key? And if I wanted to access each vector, is there a way I could do so in the same order that they appear in the list above?
So for example, if I did this:
vector<string> output1;
vector<string> output2;
vector<string> output3;
output1 = my_map["banana"];
output2 = my_map["banana"];
output3 = my_map["banana"];
which vectors would be assigned to output1, output2 and output3? I'm pretty sure it would be the same vector for all but how does unordered_map decide which one? And how can I make it so vec1 would be assigned to output1, vec2 to output2, etc?
std::unordered_map stores only one value for each key - the last you assigned to it, in your case it's vec3. If you want to store several values for each key you can use std::multimap or std::unordered_multimap.
If 2 elements have the same key then the first key value will be printed , others are ignored.
So Try the Map of Map:
Sample Snippet :
std::multimap <int, xxx> stdBindListOuter;
std::multimap <int, std::string>::iterator pos;
std::multimap <int, xxx>::iterator posOuter;
xxx--> can be user-defined..
So more flexible to use this type of versions for your case. rather than Ordered or unordered map..

does map key have an address that I can point to?

Can I treat map key as pointer?
I have a struct which member is vector of strings, and I have a map
Is it possible to fill my vector with pointers to string1 ?
example
struct A
{
vector<string> v;
}
map<string, string> m;
m["hello"] = "test";
m["world"] = "test2";
A test;
for(map<string, string>::iterator it = m.begin(); it != m.end(); it++)
test.v.push_back(it->first)
can I do this?
does map key have an address that I can point to?
Yes, like all objects it has an address.
Can I treat map key as pointer?
No, it's not a pointer. But you can take its address.
Is it possible to fill my vector with pointers to string1 ?
No, because it's a vector of strings, not pointers; so you can fill it with copies of the map keys (as your code does), but not pointers. You could have a vector of pointers:
vector<string const *> v;
and fill that with pointers to the map keys:
test.v.push_back(&it->first);
If you remove any keys from the map, then make sure you don't try to use that pointer afterwards.
In a way, yes.
If you have a key stored somewhere, or read as input, then you can use it to search the map to see if if the key exists and get its value.

store objects in vector, which is inside a map in C++

I am trying to create a map that contains a string key and an vector of myClass.
std::map<string,vector<myClass>> m;
I need to populate the vector as well and the map dynamically (reading values from a file).
class myClass{
string dataMember1;
...
myClass()
{ ... }
};
How should i proceed with it??
Also i want to be able to access the objects in the vector based on the string key.
for example:
std::map<string,vConnect>::iterator pos;
pos = mapGraph.find(string);
cout<<(pos->second)[0]->DataMemberofmyClass
will (pos->second)[0] indicate the first myClass object stored in the vector??
Thanks
Generally, when the mapped type is a container, just using []
everywhere works well; if the entry isn't present, it will be
created with an empty container, so things like:
m[key].push_back( newElement );
or
m[key].begin(), m[key].end()
or even:
if ( !m[key].empty() )
doSomethingWith( m[key].second[0] );
work correctly. If you're doing a number of operations on the
same element (as in the last two cases), you might want to hold
it in a reference:
std::vector<MyClass>& elem = m[key];
// ...
About the only exception would be if you're not modifying the
element, and you don't want to create the entry if it is empty.
In those cases, you'll need find, and a test:
std::map<std::string, std::vector<MyClass>>::const_iterator
entry = m.find( key );
if ( entry != m.end() ) {
std::vector<MyClass>& elem = entry->second;
// ...
}
Working with such nested types is not much different from working with simple map or vector. So an element of the map is a vector. Get this element and use it as a vector.
pos = mapGraph.find(string);
Returns an iterator in the map.
(pos->second)
Is the vector that is the value at this iterator. So simply use it as you would use a vector. Your code is correct apart from the fact you never check if an element was indeed found.
std::map<string,vConnect>::iterator pos;
pos = mapGraph.find(string);
if (pos != mapGraph.end()) {
cout<<(pos->second)[0].DataMemberofmyClass
}
EDIT(Thanks to us2012): in fact you had a small mistake (pos->second)[0] is an Object of MyClass so you access its members using . not using ->.

Iterator over Vector class (array)

These iterator in the collection classes confuses me. I got a Map with key of string, and value being a Vector class (similar to an array). As i understand it my iterator variable it is assigned to the map. So i should be able to to get it´s value and assign it to a new Vector class so I can read it´s contents or know it´s size etc... but how do I do this?
for (Map<string, Vector<string> > :: iterator it = array0.begin();
it != array0.end(); it++)
{
Vector<string> arr = it; // Error
Assuming your Map is a std::map, the elements of a map are pairs of (key,value), so the value is the second element of the pair:
Vector<string> arr = it->second;

C++, Error in Array

I assigned array
char words[100][100];
Now I want to save a word and its pos in the line.
Say line has "hi Iam a programmer". Now I want to save
string word;
while(line){
//called a function to get the word and position.
words[word]["pos"] = pos;
}
I have split the words and saved in the string word, but when I try to save I get error.
"No viable overloaded operator[] for type 'char[100][100]"
What am I doing wrong?
You are trying to use array as a map. You can't use strings as array index. The structure you need is std::map<std::string, std::map<std::string, int> >
std::map<std::string, std::map<std::string, int> > m;
m["foo"]["bar"] = 10;
char[100][100] is a multidimensional array of single characters, which can be used to store fixed-length strings. It can be indexed using integer variables, not strings.
It looks like you want to use std::map<std::string, std::map<std::string, int> > or similar.
You cannot use a string as an index in C++ arrays. What you need is a map:
std::map< std::string, std::map<string, int> > words;
Then you have to:
words[word]["pos"] = pos;
But, what other data would you be saving other than pos? If not, then why do you want to make it a 2 dimensional data structure? Can't you just:
positions[word] = pos;
Where positions is of type std::map<std::string, int>.
EDIT: As pointed out by Mike, not using pointers anymore.