0

I have the following code for add a structure to an unordered_set. Now i want to search if a name of a student is already in the unordered_set. How do i do this? When i create a key i need to pass three parameters but i want to search just for the first one, the name. If i create a key just for the first parameter i got an error.

#include <iostream> 
#include <unordered_set>

using namespace std;

struct Person {
    string name, biology;
    int scoreBio;

    //param constructor
    Person(string pName, string pBiology, int pscoreBio)
    {
        name = pName;
        biology = pBiology;
        scoreBio = pscoreBio;
    }

    bool operator==(const Person& h) const
    {
        return name == h.name && biology == h.biology && scoreBio == h.scoreBio;
    }
};

class MyHashFunction {
public:

    // We use predfined hash functions of strings 
    // and define our hash function as XOR of the 
    // hash values. 
    size_t operator()(const Person& h) const
    {
        return (hash<string>()(h.name)) ^ (hash<string>()(h.biology)) ^ (hash<int>()(h.scoreBio));
    }
};


int main()
{
    unordered_set<Person, MyHashFunction> Student;
    Person p1("Mauro", "Biology", 56);
    Person p2("Ram", "Singh", 67);
    Person p3("kartik", "kapoor", 56);




    Student.insert(p1);
    Student.insert(p2);
    Student.insert(p3);

    Person key("Mauro", "   ", 0);


    if (Student.find(key) == Student.end())
        cout << " not found" << endl << endl;
    else
        cout << "Found " << endl << endl;

    for (auto e : Student) {
        cout << e.name << " " << e.biology << " " << e.scoreBio << endl;
    }

    return 0;
}

lastìada
  • 5
  • 3
  • 1
    Perhaps an `unordered_map` / `unordered_multimap` (where `name` is the key) would be better? – Ted Lyngmo Sep 17 '19 at 13:43
  • 1
    Possible duplicates: https://stackoverflow.com/questions/7042578/how-to-find-an-object-with-specific-field-values-in-a-stdset and https://stackoverflow.com/questions/20317413/what-are-transparent-comparators depending on how you want to do this. – NathanOliver Sep 17 '19 at 13:48

1 Answers1

0

The find function in unordered_set searches for keys in the set. It looks for a match against a Person, since that's the type of the key in the map. There are no Persons in the map with a value of { "Mauro", " ", 0 }, so the find call is returning end().

There's no provision in the member find call for searching for part of the key.

You could use the free algorithm find with a custom predicate here:

std::find(Student.begin(), Student.end(), 
          [] (const Person &p) { return p.name == "Mauro"; });

but that will perform a linear search of the collection, not a hash-based lookup.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45