Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multimap Problem C++ 1

Status
Not open for further replies.

TotalInsanity

Programmer
Oct 18, 2006
20
0
0
GB
Hello All,

I could do with some more expert help so I have come here to seek some out!

Can someone help me with this multimap problem in c++.

I am wanting to create a multimap using two keys and a data value. I understand that they normally use 1 key and a data value as a pair, but I need two keys.

I have created a class here to use two keys:

Code:
class Keys {
public:
Keys(double k1, double k2) : key1(k1), key2(k2) { }
bool operator<(const Keys &right) 

const 
{
return (key1 < right.key1 && key2 < right.key2);
}

double key1;
double key2;
};

I have then created my map definition from the STL as follows:
Code:
typedef multimap<Keys, string> locationMultimap;
	locationMultimap TestMap;

The multimap is populated from a text file containing two doubles,which I want to use as keys, hence the class and a string data type.

I have successfully inserted this data using the following:
Code:
TestMap.insert(pair<Keys,string>(Keys(PlacePointC, PlacePointD), strPlace));

PlacePointC, PlacePointD are doubles and strPlace is the string of data. This works as it uses the class to populate the multimap with the two keys I want.

The trouble I am having is when I try to use find the find a specific set of keys.

I am using:
Code:
locationMultimap::iterator post = TestMap.find(Keys(dLatitude,dLongitude));

This is creating an interator and calling find on the multimap passing the two keys I want to find using my class. The two double keys are values of type double (dLatitude, dLongitude).

It does a lookup on the map but then displays the wrong data found when I try to cout it to the console.

Can anyone help to explain to me what is wrong here????

If I try to do a find using dLatitude as '52.15' and dLaongitude as '4.15' the string associated with this is 'Aberaeron' but instead of finding this 'double' key and displaying aberaeron it shows me another one at a totally different keys location in the map??

PLEASE PLEASE HELP ME, IT's DRIVING ME NUTS!!
 
Can I just add, If I do not use the class created, and only use one pair <key, data> in the multimap it finds the correct key straight away.

I really need to use two keys through as I'm using co-ordinates with an associated data value and these must be stored in a multimap.

I'm guessing I've been an idiot and there is something wrong with my class definition!
 
I'm guessing the problem is due to your comparison function not providing a strict ordering of the keys. For example, according to your definition of "less than," each of the following keys is less than the other:

[tt](1, 10)[/tt] and [tt](10, 1)[/tt]

So which order should they go in? The map can't tell.


The solution would be to give a priority to the two keys and sort by one before sorting by the other. For example:
Code:
bool operator < () (const Keys &right) const
{
    // Only consider the first keys unless they differ
    if (key1 != right.key1)
        return key1 < right.key1;

    // Then use the second keys to break a tie
    else
        return key2 < right.key2;
}

That function would always sort [tt](1, 10) < (10, 1)[/tt].


Of course, your function will be comparing doubles, not integers, so you'll need to introduce some appropriate delta instead of a straight == operation.
 
Oops. The comment "unless they differ" should, of course, read "unless they're the same."

And I guess I never actually used an ==, so that function may work for your doubles as written; a delta might still be appropriate, though.
 
Thankyou my friend for your valuable time.

This no makes perfect sense to me, now it's been explained.

I have tested your explanation and it works perfectly.

Thanks again, I was tearing my hair out, now I may still have some sanity left :O)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top