Search code examples
c++stlsetfunctor

set , and comparing/sorting functor or less operator


I have problem with set. I don't know what I'm doing wrong. Maybe some one of you can help me. So lets begin , the output of my program should be :

Iksinski Adam, Kowalski Jan, Nowak Adam, Nowak Jan,

So its sorted by first string.

And here's my program :

#include <set>
#include <iterator>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
class Person{
public:
Person(){}
Person(string v , string v1):nazw(v),imie(v1){}
bool operator<(const Person & K) const
{
    return ((this->getN()>K.getN())?0:1);
    //return ((this->getN()<K.getN())?1:0);
}
string getN()const
{
    return nazw;
}
/*
bool operator()(Person & K, Person & K1)
{
    return ((K->getN()<K1.getN())?1:0);
}
*/
friend ostream& operator<<(ostream & o , const Person&K)
{
    o << K.nazw << " " << K.imie;
    return o;
}
private:
string nazw,imie;
};
struct cmp
{
    bool operator()(const Person &K , const Person &K1)
    {
        return ((K.getN()<K.getN())?1:0);
    }
};
int main()
{
//typedef set<Person> kontener_typ;
typedef set<Person,cmp> kontener_typ;
kontener_typ c;
c.insert(Person("Nowak","Jan"));
c.insert(Person("Nowak","Adam"));
c.insert(Person("Kowalski","Jan"));
c.insert(Person("Nowak","Adam"));
c.insert(Person("Iksinski","Adam"));
std::copy (c.begin(), c.end(), ostream_iterator<Person>(cout, " ,"));
std::cout << std::endl;
}

Ok so in main i can only edit typdef , and copy function ( but I need to use it to output the set). Like you see i tried to overload operator< in Person (because set compering Person to Person) but it doeasnt work . I also trying with functor but it then the output looks like

Iksinski Adam ,Nowak Adam ,Kowalski Jan ,Nowak Adam ,Nowak Jan ,

So second string should be deleted .

Good luck :).


Solution

  • You must compare by both last and first names:

    bool operator<(const Person & other) const
    {
        if ( getN() < other.getN() )
          return true;
        if ( other.getN() < getN() )
          return false;
        if ( imie < other.imie() )
          return true;
        return false;
    }
    

    Or, if you want to use struct cmp:

    struct cmp
    {
        bool operator()(const Person &K , const Person &K1)
        {
          if (K.getN() < K1.getN())
            return true;
          if(K1.getN() < K.getN())
            return false;
          if(K.imie < K1.imie) // will need a friend declaration or a getter() func
            return true;
          return false;
        }
    }
    

    If you have C++'s std::tie, then the guts of either function gets much simpler:

    return std::tie(nazw, imie) < std::tie(other.nazw, other.imie);
    return std::tie(K.nazw, K.imie) < std::tie(K1.nazw, K1.imie);