Search code examples
c++hashtableunordered-set

Hash function in an unordered_set


I am using an unordered_set to implement a hash table. I can't figure out how to use the find function. I keep getting a seg fault when I run this code. I know its because find() is not finding an element but it should. My question is how do I properly use the find with the custom hash function I have provided?

unordered_set<Play*, Play::Hash> hashedData
unordered_set<Play*>::iterator got;

for (int i = 0; i < 10; ++i) {
  got = hashedData.find(data[i]);

  cout << (*got)->getSummary() << endl << endl;
}

data is just a

vector<Play*>

and my hash function looks like this

struct Hash {
    size_t operator()(Play* const &x) const {
      size_t t = 0;
      static int hash = 0;

      string u = x->getOffense();
      string v = x->getDefence();
      string w = x->getPlayDesc();

      t = u.length() + v.length() + w.length();
      t += hash;
      ++hash;

      return t;
    }
};

Solution

  • I know the root cause why you can't find the element which it should.

    Do you use staic variale in you Hash function.

    Change you Hash function to like this:

    struct Hash
    {
        size_t operator()(Play* const &x) const 
        {
            size_t t = 0;
            string u = x->getOffense();
            string v = x->getDefence();
            string w = x->getPlayDesc();
    
            t = u.length() + v.length() + w.length();
            return t;
        }
    };
    

    This function has problem, when the same object A call this function twice, the result is different. Because you use a static variable static int hash = 0;. So in your case when you construct the hashedData, the function Hash call once, when you use find function, the same object call Hash again, but you got different result, so the funtiocn find return hashedData.end().

    when you call cout << (*got)->getSummary() << endl << endl;, you will meet a seg fault. you should do like this:

    for (int i = 0; i < 10; ++i) 
    {
        got = hashedData.find(data[i]);
        if (got != hashedData.end())
        {
            cout<<(*got)->getSummary()<<endl;
        }
    }