4

I'm writing a code to check if a person has visited a particular place before or not. If true, do nothing. Otherwise, add the new place to the list of visited place I'm using map to store the student name as a key and array the store places as follows,

#include<map>
using namespace std;

map<string,string[]> stu_plac;
map<string,string[]>::iterator it;

I could not find the right way to search across the map.

I tried the following:

bool exist=false;
if(stu_plac.count(name))
{
    it=stu_plac.find(name);
    for(auto tt=(*it).second.begin(); tt!=(*it).second.end(); tt++)
    {
        if (tt.compare(place)==0)//exist
        {
            exist=true;
        }
        break;
    }
    if (!exist)
    {
        (*it)second[++tt]=place;
    }
}
else
{
    stu_plac.insert(pair<string,string[]>(name,place));
}

I think the problem is with the array of string iterator. Can you please help me to find the correct way to do this. Do I need to use multimap or other data structer to do this??

4 Answers 4

5

Data structure like map<string, vector<string> > will work.

You can use for (size_t i = 0; i < it->second.size(); i++) to traverse the vector.

Sign up to request clarification or add additional context in comments.

8 Comments

It will be also possible with iterators: std::vector<std::string>::const_iterator vectorIt = it->second.begin();
Thanks this works, the problem now is with the compare function, I wrote it as if ((*tt).compare(place)==0) but does not work any suggesion for this and the insertion function
Try if ((it->second)[i].compare(place)==0).
As for the insertion function, use iter->second.push_back(place).
Usually I use a pointer, vector<string>* p = &it->socond. Use (*p)[i] to access, and p->push_back(element) to insert.
|
4

It looks like you wanted a map of string -> places

typedef map<string,std::set<string> > Map;

Adapting it for your snippet (which had many problems, starting with the confusing formatting...):

#include<map>
#include<set>
#include<string>
using namespace std;

typedef map<string,std::set<string> > Map;
typedef Map::iterator It;

int main()
{
    bool exist=false;
    Map stu_plac;
    string name = "name";
    string place = "0.0.0.0";

    It it = stu_plac.find(name);
    if (stu_plac.end() != it)
    {
        std::set<string>& visits = it->second;
        exist = visits.end() != visits.find(place);

        if (!exist)
            visits.insert(place);
    }
}

But in reality you may prefer to use std::multimap

Comments

2

I wouln't use an array because I can't know it's size, I prefer using a vector or a list, and instead of using a boolean variable I would insert and then break the loop, so my algorithm would be like:

    std::map<std::string, std::list<std::string> > stu_plac;
    std::map<std::string, std::list<std::string> >::iterator it;
    std::string myName("Edu");
    std::string myPlace("Madrid");

.....

for( it = stu_plac.begin(); it != stu_plac.end(); it++){
            if(it->first == myName){
                    std::list<std::string>::iterator place = std::find(it->second.begin(), it->second.end(), myPlace);
                    if(place == it->second.end()){
                            it->second.push_back(myPlace);
                            break;
                    }
            }
    }

Look that you can use the iterator you got to add the city you want.

By the way, I wouldn't use "auto" variable if it's not C++11.

Comments

0

An array in C++ is one of the types or constructs inherited from C so the built-in array "type" doesn't have any iterators. It also doesn't track its current size so you cannot get begin and end iterators of an array without also storing its size.

Use std::map< std::string, std::vector<std::string> > instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.