-5

I'm trying to find the occurrences of an object in a std::multimap

Here is my object Point:

class Point
{
public:

    Point(string id, float x, float y, float z);

    string m_id;
    float m_x;
    float m_y;
    float m_z;

    //I want to count with this operator
    bool operator==(const Point &point) const
    {
        return point.m_id == m_id;
    }

    bool operator <( const Point &point ) const
    {
        return ( m_y < point.m_y );
    }

};

Here is my function (solution):

int countOccurences(multimap<Point, string> multimap, Point point)
{
    int result = 0;

    for (auto it = multimap.begin(); it != multimap.end(); it++)
        if (it->first == point)
            result++;

    return result;
}

My main:

multimap<Point, string> places;

Point point1("point", 0, 0, 0 );
Point point2("cake", 0, 0, 0 );
Point point3("point", 0, 0, 0 );

places.insert(make_pair(point1, ""));
places.insert(make_pair(point2, ""));
places.insert(make_pair(point3, ""));

cout << "CORRECT = 2" << endl;
cout << "COUNT = " << places.count(point3) << endl;
cout << "MY_COUNT = " << countOccurences(places, point3) << endl;

Initially, I wanted to count the number of occurrences with the operator==, but it was counting with the operator<. Using the function countOccurrences() is my solution.

kyu
  • 111
  • 1
  • 10
  • 5
    [You need to create a Minimal, Complete, and Verifiable Example.](http://stackoverflow.com/help/mcve) – Xirema Mar 18 '16 at 15:59
  • 1
    For one thing, we have no idea what an `S` is. – David Schwartz Mar 18 '16 at 16:00
  • 4
    keys in a map have to be unique. The key either exists or there is only one. If you want to see if a key exist then use [`std::map::find()`](http://en.cppreference.com/w/cpp/container/map/find) – NathanOliver Mar 18 '16 at 16:01
  • 2
    Maybe std::multimap should be used instead. However why is the code not using map::find()? – drescherjm Mar 18 '16 at 16:03
  • 1
    Use `map::count` ! http://en.cppreference.com/w/cpp/container/map/count – Roddy Mar 18 '16 at 16:06
  • Show how you have defined `operator<<` for `O`. – R Sahu Mar 18 '16 at 16:06
  • 1
    Without seeing the code where objects are added to the map it's rather difficult to say precisely why this isn't working. @Xirema's comment about posting a minimal, complete, and verifiable example is pertinent here. Please edit your question and include such an example. Thanks. – Bob Jarvis - Слава Україні Mar 18 '16 at 16:06
  • 1
    @BobJarvis even though this isn't a complete sample, it has enough information to say why it isn't working as expected. – Mark Ransom Mar 18 '16 at 16:09

2 Answers2

4

But it doesn't works, il only returns 1 and there are at least 2 objects in my map that have same id

It's a std::map. You cannot have two objects with the same key, and I assume you're trying to use the m_id filed of O as your key. Try using std::multimap instead.

And, to count the number of items, use map::count() (which for std::map can only return one or zero!)

Roddy
  • 66,617
  • 42
  • 165
  • 277
  • 1
    ... And consider using `map::find(T)` – user16 Mar 18 '16 at 16:12
  • "You cannot have two objects with the same ID." actually this not quite true. You assumed that `id` is used as a key for `std::map` but nothing shows that in the code. – Slava Mar 18 '16 at 16:17
  • @Slava, based on the code shown that was probably the easiest assumption to make :) – Roddy Mar 18 '16 at 16:19
  • @Roddy maybe so, but you should mention that in the answer – Slava Mar 18 '16 at 16:20
  • @Slava. Actually it's pretty clear in the code. The map key type is of `O` and the equality operator for `O` compares the `m_id` field. So the map can't contain two objects with equal `m_id`. Referring to that as 'id' isn't a huge leap. – Roddy Mar 18 '16 at 19:31
  • 1
    @Roddy equality operator is not used by map, so in theory object could be sorted by different field or their combination and then 2 objects with the same m_id can be in the map and it would make sense to use `std::count()` instead of `std::map::count()`. Most probably this is not the case, but possible. So if you make an assumption you should mention it, otherwise your answer could be completely incorrect. – Slava Mar 19 '16 at 02:12
  • @slava "equality operator not used by map". Wow, I hadn't realised that. – Roddy Mar 19 '16 at 22:59
0

Since you use a std::map, you only have one value for each key. If you've inserted different values for one key, then you have overwritten previous ones with newer ones.

As pointed out in the comments, avoid the std algorithms that std::map has its own optimized versions of. Ones like std::count_if and std::find_if are not in std::map though.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
  • 1
    Don't use the algorithms on a `map` or `multimap`, they're less efficient than using member functions - O(n) vs. O(log n). – Mark Ransom Mar 18 '16 at 16:13
  • "If you've inserted different values for one key, then you have overwritten previous ones with newer ones." if they are inserted by `std::map::insert` they are not overwritten – Slava Mar 18 '16 at 16:14
  • @mark - thanks for the correction, I changed that piece to better reflect this. – Johann Gerell Mar 18 '16 at 16:57
  • @slava - your clarification is correct and nothing I wrote says anything else. – Johann Gerell Mar 18 '16 at 16:59