This is probably easy but i've been awake for too long.
So I have a map< int, string> and i'm trying to use the function find
iter=mapInKey.find(int)->second;
if (iter != mapInKey.end() )
{
outFileTxt << iter;
}
But I get this error: no matching function for call to std::map<int, std::basic_string<char> >::find(std::string&)
All I want to do is output the other pair value of int
Like this
std::map <int,std::string>::iterator it = mapInKey.find( val ); //val is the integer key you search for
if(it != mapInKey.end()){
// do something
cout<< it->second; // this will print the string
}
Edit
I think you want to search by string. then you are declaring the map wrong. Use this
map<string,int> m;
m["Hi"]= 1;
m["Hello"]= 2;
map<string,int>::iterator it = m.find("Hello");
if(it != m.end())
{
cout<< it->first<<":"<<it->second<<endl;
}
Related
In c++ I need to search a vector containing a pair, in reverse, by the string. I cannot use a map because the strings are not unique and order is important. I then want to return a forward iterator if the string is found or the end iterator if the string is not found.
Please see below for my current code. I have no problem when the string is found but, if the string is not found, I get a segfault in the conditional statement in main.
vector<pair<string, int>>::iterator prev_it(const string& pred,
vector<pair<string, int>> prevpreds) {
vector<pair<string, int>>::reverse_iterator rit;
for(rit = prevpreds.rbegin();
rit != prevpreds.rend(); ++rit) {
if (rit->first == pred) {
return (rit+1).base();}
}
if(rit == prevpreds.rend()) {
return prevpreds.end();
}
}
and in main:
int main() {
vector<pair<string, int>> test;
for(int i = 0; i <= 5; ++i) {
pair<string, int> mypair;
mypair = make_pair("X"+to_string(i%4+1), i+1);
test.emplace_back(mypair);
}
string tpred = "X"+to_string(6);
vector<pair<string, int>>::iterator tit;
tit = prev_it(tpred, test);
if (tit != test.end()) {
cout << tit->first << " " << tit->second << endl;
}
else {cout << "This is the end." << endl;}
}
The code works if tpred is one of X1 to X4. If tpred is X6 (i.e. not an element of test) then I get a segfault. What I would like to be able to do is return the end forward iterator and then, as in main(), have a conditional based on this.
Edit: I am new to c++ (about a year). I am returning a forward iterator because I need to use the iterator later and this seems clearer (but I could be wrong). As far as I understand, a multimap allows non-unique keys but will order the unique keys. I should have been clearer and said time order was important, not key order. I prefer not to use auto while developing because I like to see what I container element/iterator I am using, but point taken.
You're using an iterator of a destructed object. Pass prevpreds by reference, so the iterator maintains valid.
vector<pair<string, int>>::const_iterator prev_it(const string& pred,
const vector<pair<string, int>> &prevpreds)
{
vector<pair<string, int>>::const_reverse_iterator rit;
for (rit = prevpreds.rbegin();
rit != prevpreds.rend(); ++rit)
{
if (rit->first == pred)
{
return (rit + 1).base();
}
}
return prevpreds.end();
}
int main()
{
// ...
vector<pair<string, int>>::const_iterator tit; // <-- uses const iterator
tit = prev_it(tpred, test);
// ...
}
I have this code:
bool Sparse_Matrix_RL::removeColsFromRow(unsigned int row_id, std::list<unsigned int>& col_ids)
{
std::list<unsigned int>::iterator c_str,s_str;
std::list<unsigned int>::iterator c_end = col_ids.end();
std::map<unsigned int, std::map<unsigned int, double> >::iterator m_str;
if (data_Matrix.count(row_id))
{
m_str = data_Matrix.find(row_id);
}
else
{
std::cout << "Row not found";
return false;
}
std::map<unsigned int, std::map<unsigned int, double> >::iterator m_end = data_Matrix.end();
std::map<unsigned int, std::map<unsigned int, double> >::iterator row;
if (m_str != m_end)
{
for (c_str = col_ids.begin(); c_str != c_end; c_str++)//col_id's are sorted
{
m_str->second.erase(*c_str);
}
}
if (data_Matrix[row_id].size() == 0)
data_Matrix[row_id][row_id] = 0;
return true;
}
And following is my function call:
list<unsigned int>::iterator direc_Str = direc_dofs_list.begin();
list<unsigned int>::iterator direc_End = direc_dofs_list.end();
list<unsigned int>::iterator p;
for (int rid = 0; rid < total_rows; rid++)
{
p = std::find(direc_Str, direc_End, rid);
if (p == direc_End)
stiffness_matrix->removeColsFromRow(rid, direc_dofs_list);
}
I am passing row Ids and a list to function. In function, first of all I am finding that row in map and after finding that I am erasing data from that row while giving it columns which are in list. Now erase function find that location and erase it. I want erase function to start find index from next index each time after erasing one. I want to do it for speedup.
Since col_ids is sorted, you can leverage that order and simply traverse the list and map together, like in the merge step of a merge sort, and pick off indices that are matched.
auto mm_itr = m_str->second.begin(), mm_end = m_str->second.end();
while(c_str != c_end && mm_itr != mm_end) {
if(*c_str < mm_itr->first) // c_str smaller, progress it
++c_str;
else if(*c_str > mm_itr->first) // key is smaller, progress it
++mm_itr;
else {
mm_itr = m_str->second.erase(mm_itr); // They are equal, erase and grab the returned iterator
++c_str; // Can also progress in the list now
}
}
For example I have a map like this:
map<string , map <int , int>> example;
and an iterator:
map<string , map <int, int>>::iterator iter;
string word;
And i want to access to the inner map :
for(iter = example.begin();iter!=example.end;iter++){
iter = Map.find(word);
iter -> second //
}
What i should do to access the inner map just for example if iter->second ==4 -it's is not correct ,
or can i do (iter->second)->second ??? can u give me an advise. i undestand that iterator is giving me a pair of (int,int) so i tryed to do another iterator map ::iterator i; and to assing iter->second = i, but it didin't help me to;
For complex types use typedef it will make your life much easier:
typedef std::map< int, int > Ints;
typedef std::map< std::string, Ints > String2Ints;
String2Ints example;
std::string word;
String2Ints::iterator it = example.find( word );
if( it != example.end() ) {
Ints &innerMap = it->second;
Ints::iterator innerit = innerMap.find( 4 );
if( innerit != innerMap.end() )
std::cout << "found value for word " << word << " 4 - " << innerit->second << std::endl;
}
Also your loop and find inside is incorrect, you should either iterate over map or search for value by find(), what you do in your code does not make any sense (technically infinite loop if word is found)
iter->second is a map, so if you want to find something in it you need another find.
You can also use your iterator directly, without the for loop.
Ex:
map<string , map <int, int>>::iterator iter;
iter = example.find(word);
if (iter != example.end()){
map<int, int>>::iterator innerIter;
int key = 4;
innerIter = iter->second.find(key);
if (innerIter != iter->second.end()){
(...)
}
}
Let's assume I have a map in my code:
map <string, set<string> > myMap;
... and I want to get an element from map:
myMap.find("key");
My question is: what kind of value will myMap return if "key" doesn't exist? `
///EDIT
Can anyone point the reason of error? Compiler doesn't see any mistake but server which tests whole algorithm, doesn't accept it because of this function.
map< string, set<string> >::iterator mapIterator = container.find(key);
if(mapIterator != container.end()){
set<string>::iterator setIterator = mapIterator->second.begin();
if(!mapIterator->second.empty()){
while(setIterator != mapIterator->second.end()){
cout << *setIterator << endl;
++setIterator;
}
}else{
.......
}
}else{
..........
}
It returns an iterator equal to myMap.end(). You can easily test for that:
auto it = myMap.find("key");
if (it == myMap.end())
{
std::cout << "key not found\n";
}
http://en.cppreference.com/w/cpp/container/map/find
find returns an iterator, so if the key does not exist it returns an end iterator.
eg:
std::map< int, int > some_map;
if ( some_map.find( 10 ) != some_map.end() )
{
... key exists ...
}
else
{
... key does not exist ...
}
An iterator pointing past the end of the collection. This is true for all stl containers. Check for the value with
map <string, set<string> > myMap;
map <string, set<string> > :: iterator iter = myMap.find( "x" );
if( iter != myMap.end())
{
// ... do something
}
std::map::find returns iterator (or const_iterator) equal to map.end() if key is not present.
Return value
Iterator to an element with key equivalent to key. If no
such element is found, past-the-end (see end()) iterator is returned.
http://en.cppreference.com/w/cpp/container/map/find
Example:
std::map<std::string, int> m;
if( m.find( searchedString) != m.end()) {
//... present
} else {
//... not found
}
I have a map<int, map<int, int>>.
The first key stands for node, the second key stands for an attribute, and the 'deepest' element represents a particular value.
I need to check that element, but doing the following unnecessary adds keys to my map:
map<int, map<int, int>> test;
if (test[4][3] > 5)
{
//do something
}
The alternative as I think of it is
map<int, map<int, int>> test;
if (test.find(4) != test.end())
{
if (test[4].find(3) != test[4].end())
{
if (test[4][3] > 5)
{
//do something
}
}
}
Is there a better way to do this? I don't know if there exists the key [4][3] in the map, and I don't want to unnecessarily add it. Thanks!
This should work - first you search in the first map and saves the returned iterator, then if that iterator is valid you search the map that he points to and saves the result in another iterator, and if he's valid that means that the objects you seek exists and you just check the value of it:
map<int, map<int, int>> test;
map<int, map<int, int>>::iterator it1;
map<int, int>::iterator it2;
if ((it1 = test.find(4)) != test.end())
{
if ((it2 = it1->second.find(3)) != it1->second.end())
{
if (it2->second > 5)
{
//do something
}
}
}
return 0;
Not fundamentally different from Tomer Arazy's suggestion, but making use of C++11's decltype to get rid of repeated type declarations (correcting which can be tedious when you modify the data type of the map):
#include <map>
#include <iostream>
int main()
{
using std::map;
map<int, map<int, int>> test;
test[4][3] = 6;
decltype(test.begin()) outer;
decltype(test.begin()->second.begin()) inner;
if (((outer = test.find(4)) != test.end())
&& ((inner = outer->second.find(3)) != outer->second.end())
&& (inner->second > 5))
std::cout << "Found!" << std::endl;
return 0;
}
(Note that the argument of decltype() isn't evaluated, so this works even if the map is empty.)
This will obviously only work with C++11.
Another thing to mention in the context of C++11 is that std::map has now an at() function similar to std::vector. It returns the value for a given key, and throws an exception if the key doesn't exist. This only a useful idea if you consider the non-existence of the key as an error condition. But if so, you could use
if (test.at(4).at(3) > 5)
std::cout << "Found!" << std::endl;
And then possibly catch the std::out_of_range exception somewhere.
I think this might make it a bit easier to see what's going on:
map<int, map<int, int>> test;
map<int, map<int, int>>::iterator outer = test.find(4);
if (outer != test.end())
{
map<int, int>::iterator inner = outer->second.find(3);
if (inner != outer->second.end())
{
if (inner->second > 5)
{
//do something
}
}
}
return 0;