2010-10-11 9 views
5

Mam klasy tak:Czy mogę użyć zmiennej składowej jako klucza do hash_set/hash_map?

class Foo 
{ 
    long long Id; 
    string x; 
    string y; 
    // other member variables and functions 
}; 

chciałabym zapisać to w hash_set (lub hash_map), ale użyć zmiennej ID Użytkownika jako klucz do wrzucania i poszukiwania. Nie jestem pewien, jak mogę to zrobić. Pomyślałem o następujących sposobach, ale żaden z nich nie jest naprawdę dobry:

1) Mogę napisać niestandardową funkcję skrótu, która będzie mieszała obiekt za pomocą Id, ale wtedy nie mogę użyć metody find() na hash_set wyszukaj element według Id (long long), ponieważ będzie on wymagał przekazania obiektu Foo.

2) Mogę zduplikować identyfikator i utworzyć hash_map<long long, Foo> zamiast hash_set<long long, Foo>, ale mam 100 milionów wystąpień tych obiektów, więc wolałbym nie powielać pola Id.

3) pole id mogę przenieść poza Foo a następnie zrobić hash_map<long long, Foo>, ale byłoby to swego rodzaju bałagan ponieważ id jest używane wewnętrznie przez klasę i byłoby lepiej, aby utrzymać go z Foo.

Wszelkie pomysły? To, czego szukam, to sposób na przechowywanie obiektów Foo, ale można je wyszukać w hash_set przy użyciu long long (według Id).

Dzięki!

+0

Idź z trzecim podejściem. – Grozz

+0

Drugi też jest w porządku. – sellibitze

+0

Jaki jest wzór użycia? Czy konfigurujesz to raz, a potem czytasz tylko z niego, czy ciągle modyfikujesz zestaw? – sbi

Odpowiedz

0

To może nie być szczególnie eleganckie rozwiązanie, ale działa: zdefiniować operator < (i operator == jak dobrze, jak sugeruje CashCow) na swoją klasę, która porządkuje obiekty oparte na polu Id, wtedy kiedy chcesz zrobić find , przekaż obiekt obojętny, który zawiera szukany obiekt Id.

+0

Działa doskonale do standardowego zestawu lub mapy, nie jest tak doskonały dla kontenerów opartych na haszyszu. "Operatorem <", mam na myśli. –

+0

Dlaczego nie? Myślałem, że kontenery oparte na hashach nadal zależą od 'operatora <', aby ostatecznie zapewnić, że dwa obiekty są równe. – casablanca

+0

Zarówno 'hash_map', jak i' unordered_map' wydają się mieć funktor porównania dla równości, nie mniejszy niż. –

0

1) mogę napisać funkcję zwyczaj mieszania która Hash obiekt używając Id, ale wtedy nie mogę użyć find() metodę na hash_set do Lookup element przez ID (długi długo), ponieważ będzie wymagać przesłania obiektu Foo.

Jest to typowy problem ze standardową mapą i ustawionymi kontenerami. Dodaj konstruktor lub element statyczny, który tworzy obiekt porównania, obiekt z poprawnym tylko elementem klucza.

0

Opcja 2 jest najlepszym wyborem spośród trzech, które dałeś. Jeśli masz na to ochotę, możesz napisać niestandardowy hash_set (nawet zwykłe opakowanie), aby zapewnić to, co chcesz. W takim przypadku wolałbym opcję 1. Można łatwo dodać funkcję znajdowania, która ma tylko kluczową wartość i dostosowuje ją do wewnętrznej funkcji wyszukiwania, co zapewnia wszystkie korzyści.

0

Nie mam z tym większego doświadczenia, ale boost :: multiindex jest domyślnie wbudowany w funkcję boost :: hash i ma jawną pomoc w wyszukiwaniu obiektu w hashu za pomocą tylko klucza znalezionego w obiekt.

0

Jeśli nie znajdziesz właściwego rozwiązania dla kontenerów hash_set/hash_map, możesz rozważyć użycie implementacji tabeli mieszającej uthash, która obsługuje bezpośrednio przypadek użycia. Jest to jednak C i jest oparte na makrach, ale jest to jedna z najpopularniejszych implementacji tablic asocjacyjnych, które istnieją.

Powiązane problemy