Find function in vector and the keys of a map - c++

The Vector find function can search an inserted value even if you try and find by providing substring . Is this same in case of the keys of a map ?
int main()
{
vector<string> v;
v.push_back("text");
v.push_back("[[text");
v.push_back("text");
for (unsigned i = 0; i < v.size(); i++)
{
if (v[i].find("[[") == 0)
{
v[i].append("]]");
}
}
}
Here it finds "[[text" and makes it "[[text]]" .
I tried it in map but code crashes on run time ,. I am using Dev c++
int main()
{
std::multimap<string, string> m;
std::multimap<string, string> intersection;
std::multimap<string, string>::iterator it8;
m.insert(pair< string, string>("4-2"," 61-7" ));
m.insert(pair< string, string>("5-2"," 61-7" ));
multimap<string, string>::iterator it4;
multimap<string, string>::iterator it5;
for ( it4 = m.begin(); it4 !=m.end(); it4++)
{
if (m.find("5-") == 0)
it5=it4;
}
cout << " result of 5 search is" << (*it5).first << ", " << (*it5).second <<endl;
m.clear();
getchar();
}

(Sample correct code on ideone)
The error is that this line
if (m.find("5-") == 0)
will never succeed. You maybe be surprised at this. m.find("5-") searches through the entire map looking for an entry whose key is exactly equal to "5-". Your keys are "4-2" and "5-2".
Do you wish to find keys which contain the substring "5-"? Then you need something like
it4->first.find("5-"); // check if the key string at this entry contains "5-"
I think you want a loop like this:
multimap<string, string>::iterator it4;
for ( it4 = m.begin(); it4 !=m.end(); it4++)
{
if (it4->first.find("5-") != string :: pos)
cout << " result of 5 search is" << it4->first << ", " << it4->second <<endl;
}
As others have pointed out, you are not interested in the the find method of vector or map. You are interested in the find method of string - this is quite different. The title of your question is a little misleading as a result (unintentionally).

The problem with std::set<> is that you cannot modify its elements in place because you could violate the ordering it has. You can however iterate from set.begin() to set.end() using iterators (instead of operator[]) and remove and reinsert modified elements.

Related

How to point to n'th char from string in vector C++

When I iterate over a vector using an int (say i), I can easily say:
vector<string> V;
V[i][g]
in which (int) g is the g'th character of the string in V[i]
When I am in a loop and want to keep iterating although I will delete items (from V) on the run, I want to make use of:
vector<string>::iterator it;
and then, I thought, the g'th character of V[i] would - in the loop - be:
for (it = V.begin() ; it != V.end() ; it++)
*it[g]
or, more logically in my eyes:
it[g]
bit neither work... Can anyone tell me how to get the g'th char of V[i] in this iterator-using variant?
What you want to do is
for (std::vector<std::string>::iterator it = V.begin(); it!=V.end(); it++) {
std::cout << *it << std::endl; // whole string
std::cout << (*it)[2] << std::endl; // third letter only
}

Inserting elements into map with set value and printing the set

I'd like to build a map with an integer key and a set value. I'd like to know what the syntax for doing that should be. Also, once I have the map filled with some key and value pairs, how should the set value be printed out?
map<int, set<int> > mymap;
map[node]= // Code to insert elements into set???
for( map<int, set<int> >::iterator ii=mymap.begin(); ii!=mymap.end(); ++ii)
{ //Code to print map??? }
Also, is there some way to add elements to a set for a key that's already been created? Any help would be much appreciated!
To insert in the set you can use the method insert. If the map key doesn't exist (node), it will be created.
See the example:
node = 1; // a map key
map<int, set<int> > mymap;
mymap[node].insert(99); //insert 99 in the set corresponding to the map key 1
for( map<int, set<int> >::iterator ii=mymap.begin(); ii!=mymap.end(); ++ii)
{
cout<< "Key: "<< ii->first << " value: ";
for (set<int>::iterator it=ii->second.begin(); it!=ii->second.end(); ++it)
{
cout << *it << " ";
}
cout << Lendl;
}

Nested loop using iterator C++

Stuck in very interesting problem.
You might have done this before in C/C++
map<string, string> dict;
dsz = dict.size();
vector<string> words;
int sz = words.size();
for(int i = 0; i < sz; ++i)
{
for(int j = i + 1; j < dsz; ++j)
{
}
}
How I will achieve the same thing using iterator.
Please suggest.
Ok.
I figure it out.
more precisely I wanted both i and j in inner loop.
here i did with iterator, sorry I have to move to multimap instead of map due to change in requirement.
vector<string>::iterator vit;
multimap<string, string>::iterator top = dict.begin();
multimap<string, string>::iterator mit;
for(vit = words.begin(); vit != words.end(); ++vit)
{
string s = *vit;
++top;
mit = top;
for(; mit != dict.end(); ++mit)
{
/* compare the value with other val in dictionary, if found, print their keys */
if(dict.find(s)->second == mit->second)
cout << s <<" = "<< mit->first << endl;
}
}
Any other efficient way to do this will be grateful.
Your final intent is not fully clear, because you start the j loop on i+1 (see comments at the end). Until you give clarity on this relationship, I propose you two interim solutions
Approach 1: easy and elegant:
You use the new C++11 range based for(). It makes use of an iterator starting with begin() and going until end(), without you having to bother with this iterator:
for (auto x : words) { // loop on word (size sz)
for (auto y : dict) { // loop on dict (size dsz)
// do something with x and y, for example:
if (x==y.first)
cout << "word " << x << " matches dictionary entry " << y.second << endl;
}
}
Approach 2: traditional use of iterators
You cas also specify explicitely iterators to be used. This is a little bit more wordy as the previous example, but it allows you to choose the best suitable iterator, for example if you want constant iterator like cbegin() instead of begin(), if you want to skip some elements or use an adaptator on the iterator, suc as for example reverse_iterator, etc.:
for (auto itw = words.begin(); itw != words.end(); itw++) {
for (auto itd = dict.begin(); itd != dict.end(); itd++) {
// do simething with *itw and *itd, for example:
if (*itw == itd->first)
cout << "word " << *itw << " matches dictionary entry " << itd->second << endl;
}
}
Remarks:
The starting of intter loop with j=i+1 makes sense only if elements of word vector are related to elements in dict map (ok, they are cerainly words as well), AND if the order of elements you access in the map is related to the order in the vector. As map is ordered according to the key, this would make sense only word would be ordered as well following the same key. Is it the case ?
If you'd still want to skip elements or make calculation based on distance between elements , you'd rather consider the second approach propose above. It makes it easier to use distance(itw, words.begin()) which would be the equivalent of i.
However, it's best to use containters taking advantage of their design. So instead of iterating trough a dictionaly map to find a word entry, it's better to do use the map as follows:
for (auto x : words) { // loop on word (size sz)
if (dict.count(x)) // if x is in dictionary
cout << "word " << x << " matches dictionary entry " << dict[x] << endl;
}

is accessing two vectors in maps impossible?

Since I am beginner to c++, I was trying to play with . So, I succeeded in
map<string,int>
And,
map <string, vector<int> >
But, I was curious if having two vectors in a map can be accessible. So, what should I do?
int main()
{
map<vector<string>,vector<int> > a;
vector<int> okay;
vector<string> knot;
knot.push_back("name1"); //this for inserting in vector<string>
knot.push_back("name2");
okay.push_back(1); //this on for vector<int>
okay.push_back(2);
a[knot]=okay;
map<vector<string>,vector<int> >::iterator i=a.begin();
cout<<i->first<<endl; //error shows here, how am i accessing this?
++i;
cout<<i->first; //this too. Function resembles the same of above. So, ERROR!!
return 0;
}
This line:
cout<<i->first<<endl;
You are doing the right thing, but i->first returns a vector because you have a map of vectors. There is no overloaded << (print) operator for vector<string> (but you could make your own). But if you:
auto temp = i->first;
for(const auto &a : temp) {
cout << a << endl;
}
This will print all the elements stored in the vector in i->first.
If you wish the print the first element stored in the vector, you can do:
cout << *((i->first).begin()) << endl; //iterator method or
cout << (i->first)[0] << endl;
Do not attempt to print vector elements without checking emptiness.

Referencing a Value from a Nested Pair in a Map

I have a map which contains an int and a nested pair of two strings:
map<int, pair<string, string> > books;
I also have a vector of strings.
vector<string> returned;
And the two iterators which accompany them:
vector<string> returned::iterator it2;
map<int, pair<string, string> >::iterator it3;
I am trying to access the first string of the pair which is nested in the map to compare it to the current string of the vector "returned". I am using two iterators to do this. However, I cannot seem to access the first string of the nested pair.
//PUT BACK BORROWED BOOKS
for (it2 = returned.begin(); it2 != returned.end(); it2++){
//SEARCH FOR POSITION OF BOOK
for (it3 = books.begin(); it3 != books.end(); it3++){
//PROBLEM IN LINE BELOW
if(it2 == (it3->second-> first))
int bookPos = it3 -> first;
}
}
Does anyone know how to reference this first string in the pair? Obviously "it->second-> first" is not the solution.
Thanks in advance.
There are two errors. it3->second is not an iterator. Also as was mentioned in comments, you are comparing it2 (iterator) with a string. Line with error should look like this:
if(*it2 == (it3->second.first))
Maps also make good lookup tables. The map key corresponds to two values represented by a pair. The example below shows how to access the key and pair values.
int main()
{
typedef map<string, pair<int, int> > op_type;
op_type op = {
{"addu", make_pair(33, 1) }
};
vector<string> this_line;
op_type::const_iterator i = op.find(this_line[0]);
if( i != op.end() )
{
cout << "key: " << i-first << endl;
cout << ".first value in pair " << i->second.first << endl;
cout << ".second value in pair " << i->second.second << endl;
}
}
Prints:
key: addu
.first value in pair 33
.second value in pair 1