2010-08-04 12 views
5

Jestem początkującym w C++. Czy ktoś może mi powiedzieć najlepszą strukturę danych w C++ do przechowywania wszystkich słów w słowniku i znaleźć, czy słowo jest obecne w słowniku. Wiem, że tabele mieszania są najlepsze, ale nie wiem, która struktura danych je wykorzystuje?Najlepsza struktura danych w C++, aby znaleźć ciąg w słowniku

Dziękuję bardzo z góry.

+0

C++ DS jest dostarczany przez standardową bibliotekę, taką jak mapy, zestawy itp. Więc który jest najlepszym DS do wyszukiwania ciągu. Przeczytam wszystkie ciągi s i szukam. – brett

Odpowiedz

9

Twoja standardowa biblioteka implementacji C++ może mieć unordered_set lub hash_set. Zasadniczo są to ta sama rzecz; pierwsza jest częścią nadchodzącego standardu C++ 0x i jest obsługiwana przez niektóre z najnowszych kompilatorów, druga pochodzi z oryginalnego SGI STL i jest zawarta w wielu standardowych implementacjach bibliotek.

+1

Czy hash_set lub unordered_set jest częścią standardowej biblioteki? – brett

+0

@brett: 'hash_set': Oficjalnie? Nie. Ale wiele standardowych implementacji bibliotek (w tym Visual C++ i libstdC++) obejmuje to. 'unordered_set': Jeszcze nie. Będzie on częścią standardowej biblioteki, gdy C++ 0x zostanie zatwierdzony w 2011 roku. Niektóre standardowe implementacje bibliotek (np. Biblioteka Visual C++ 2010) obejmują to. –

+0

Czy mogę go używać w moim kompilatorze? G ++? Jeśli nie, jaka jest najlepsza struktura danych? – brett

2

hash_map, jeśli masz go w swojej bibliotece kompilatora C++ (np. GNU C++ lub Microsoft Visual C++). Jeśli używasz innego, mniej rozpowszechnionego kompilatora, podejrzewam, że mimo wszystko możesz znaleźć przyzwoitą implementację strony trzeciej w postaci hash_map.

Nadchodzący standard C++ wywołuje zamiast tego tę samą strukturę danych: std::unordered_map.

Jeśli nie chcesz kojarzyć żadnych informacji ze słowami w słowniku, po prostu zapisz, czy słowo jest w nim obecne, możesz użyć odmian _set (zamiast _map) powyższej struktury danych wpisz nazwy.

Oczywiście wszystkie one są szablonami (tak jak wszystkie pojemniki w standardowej bibliotece C++), więc trzeba je odpowiednio utworzyć za pomocą typowej składni szablonu.

+0

Ale myślę, że będzie lepiej z zestawem słów, a nie z mapą, która jest zbiorczym kontem klucz-wartość. Jak powiedział James, każda implementacja zestawu powinna wystarczyć. –

+0

@ Hernán, jak już wspomniałem, jeśli potrzebuje tylko informacji o obecności/nieobecności, wystarczą 'hash_set' lub' unordered_set', jeśli kiedykolwiek będzie musiał zapisać jakiekolwiek informacje pomocnicze, wtedy warianty '..._ map' być lepszym (i równie skutecznym). –

0

Jeśli jedynym wymaganiem jest ustalenie, czy słowo zawiera się w stale zmieniającym się słowniku, bez potrzeby podawania jakichkolwiek innych informacji o słowie, (na przykład sprawdzanie pisowni), wówczas Bloom filter jest wydajnym struktura danych dla tego zadania.

Jeśli istnieją inne dane, które należy powiązać z każdym słowem, które należy wyszukać, std::map jest dobrym punktem początkowym ogólnego przeznaczenia.

Jeśli wymagane jest automatyczne uzupełnianie (po wprowadzeniu częściowego słowa), można użyć Prefix tree (trie).

+0

Filtr Bloom jest probabilistyczną strukturą danych; nie może dać ci ostatecznej odpowiedzi Tak/Nie. Możliwe są fałszywe alarmy, ale fałszywe negatywy nie. Jednak trie to dobry pomysł. –

4

Hashe są całkiem dobre, ale najlepszą strukturą jest trie. Możesz dostać trie z <ext/pb_ds/assoc_container.hpp> w GCC. Zobacz the online reference.

#include <ext/pb_ds/assoc_container.hpp> 
#include <string> 
#include <iostream> 

int main() { 
     pb_ds::trie< std::string, int > dict; 

     dict.insert(std::make_pair("hello", 3)); 

     std::cerr << (dict.find("hello") != dict.end()) << std::endl; 
     std::cerr << (dict.find("goodbye") != dict.end()) << std::endl; 
} 

Tylko map -jak funkcjonalność, a nie czysta set, jest przewidziane. W powyższym przykładzie dodałem manekina int jako dane do odwzorowania ... nie powinno to za bardzo szkodzić.

To, co jest nie tak, nie zadziała na zewnątrz GCC.

Z drugiej strony, non -standard tabeli mieszania (nie std:: lub ext:: cokolwiek) pozwoli Ci znaleźć tylko przybliżone wyniki, to znaczy, aby szukać wśród sum kontrolnych słów zamiast samych słów. To byłoby najszybsze i najbardziej kompaktowe rozwiązanie. Słowniki oparte na Bloom filters mogą zawierać wiele tysięcy słów w kilku kilobajtach.

+0

Dlaczego to nie działa poza GCC? Nie ma możliwości zaimportowania tych bibliotek do Visual Studio (kompilator CL)? –

+0

@YechielLabunskiy Plik jest po prostu dołączany do GCC. Może działać w MSVC, jeśli nie zależy od żadnych rozszerzeń GCC ani nie wywołuje żadnych błędów MSVC. Z pewnością warto spróbować. Trzeba by jednak potraktować to jako osobną bibliotekę stron trzecich i monitorować ją pod kątem aktualizacji. – Potatoswatter

0

Jeśli chcesz przetestować swoje własne rozwiązanie, a Twój słownik jest poprawiony, dobrym pomysłem jest perfect hash. Gwarantuje stały czas wyszukiwania.

+0

Miałem ten dokładny problem (generowanie stałych słowników) rok lub dwa temu i byłem rozczarowany, że idealne mieszanie wymaga praktycznie dwuwarstwowej struktury danych, a zatem wielu odczytów pamięci na wyszukiwanie. Kończy się to wolniej niż zwykły stary stół hashowy z łańcuchem. –

+0

FWIW, oto kod, który napisałem, aby wygenerować tabelę: http://hg.mozilla.org/tracemonkey/file/e555673c8119/js/src/xpconnect/src/qsgen.py#l1488 i do sondowania: http : //hg.mozilla.org/tracemonkey/file/e555673c8119/js/src/xpconnect/src/xpcquickstubs.cpp#l70 W praktyce generuje kilka łańcuchów o długości 3 haseł (jednak kilka wyszukiwań musi w ogóle przejść dowolne łańcuchy) . –

1

Wolałbym używać Trie. Trie będzie dobrą strukturą danych do budowy wydajnego pamięciowo słownika z szybkimi odnośnikami i tak, autouzupełnianie.

Wyobraź sobie, że jest to hashtable, zapewniające szybkie wyszukiwanie par klucz-wartość (lub po prostu wyszukiwanie kluczy), ale w przeciwieństwie do hashtable pozwala na iterację po kluczach w posortowanej kolejności.

Proszę odnieść się do Trie - Wiki w celu uzyskania dalszych informacji/odniesienia.

Powiązane problemy