저는 C++의 초보자입니다. C++에서 모든 단어를 사전에 저장하고 사전에 단어가 있는지 찾아내는 데 가장 적합한 데이터 구조를 말해 줄 수 있습니까? 나는 해쉬 테이블이 최고라는 것을 알고 있지만 어떤 데이터 구조가 그들을 사용하는지 모른다.C++의 최상위 데이터 구조로 사전에서 문자열 찾기
대단히 감사합니다.
저는 C++의 초보자입니다. C++에서 모든 단어를 사전에 저장하고 사전에 단어가 있는지 찾아내는 데 가장 적합한 데이터 구조를 말해 줄 수 있습니까? 나는 해쉬 테이블이 최고라는 것을 알고 있지만 어떤 데이터 구조가 그들을 사용하는지 모른다.C++의 최상위 데이터 구조로 사전에서 문자열 찾기
대단히 감사합니다.
C++ 구현의 표준 라이브러리에는 unordered_set
또는 hash_set
이있을 수 있습니다. 그것들은 본질적으로 같은 것이다. 전자는 앞으로 출시 될 C++ 0x 표준의 일부이며 최신 컴파일러에서 지원되며 후자는 원래 SGI STL에서 제공되며 많은 표준 라이브러리 구현에 포함됩니다.
표준 라이브러리의 hash_set 또는 unordered_set 부분입니까? – brett
@brett :'hash_set' : 공식적으로? 아니요. 그러나 많은 표준 라이브러리 구현 (Visual C++ 및 libstdC++ 포함)에는이 라이브러리가 포함되어 있습니다. 'unordered_set' : 아직 없습니다. 2011 년 언젠가 C++ 0x가 승인되면 표준 라이브러리의 일부가 될 것입니다. 일부 표준 라이브러리 구현 (예 : Visual C++ 2010 라이브러리)에는이 라이브러리가 포함되어 있습니다. –
내 리눅스 컴파일러에서 사용할 수 있습니까? G ++? 가장 좋은 데이터 구조는 무엇입니까? – brett
hash_map, C++의 컴파일러 라이브러리 (예 : GNU C++ 또는 Microsoft Visual C++)에있는 경우 컴파일러가 아닌 다른 컴파일러를 사용하고 있다면 어쨌든 hash_map
의 제 3 자 구현을 찾을 수있을 것으로 생각됩니다.
앞으로 나올 C++ 표준에서는 이와 동일한 데이터 구조 std::unordered_map
을 대신 호출합니다.
사전에있는 단어와 정보를 모두 연관시키지 않으려면 단어가 포함되어 있는지 여부 만 기록하면됩니다 (_map
대신) _set
변형을 사용할 수 있습니다 이름을 입력하십시오.
물론이 템플릿은 모두 (C++ 표준 라이브러리의 모든 컨테이너로) 템플릿이기 때문에 일반적인 템플릿 구문을 사용하여 적절하게 인스턴스화해야합니다.
하지만 그는 단어 조합으로 더 좋을 것이라고 생각합니다. 연관 키 값 컨테이너 인지도가 아닙니다. 제임스 (James)가 말했듯이, 어떤 설정 구현으로도 충분합니다. –
@Hernán, 내가 언급했듯이 그가 존재/부재 정보 만 필요로한다면'hash_set' 또는'unordered_set'만으로 충분할 것입니다. 만약 그가 보조 정보를 기록 할 필요가 있다면'... map '변종은 더 좋게 (그리고 효율적으로). –
단어에 대한 다른 종류의 정보 (예 : 맞춤법 검사기)가 필요없이 절대로 바뀌지 않는 사전에 단어가 포함되는지 여부를 결정하는 유일한 요구 사항은 Bloom filter이 효율적입니다 이 작업을위한 데이터 구조.
각 단어와 연결할 다른 데이터가있는 경우 std::map
은 좋은 범용 시작점입니다.
자동 완성이 필요한 경우 (부분 단어를 입력 한 경우) Prefix tree (trie)을 사용할 수 있습니다.
블룸 필터는 확률 론적 데이터 구조입니다. 그것은 당신에게 최종 Yes/No 응답을 줄 수는 없습니다. 거짓 긍정은 가능하지만, 잘못된 음수는 아닙니다. 그래도 trie는 좋은 생각입니다. –
해시는 꽤 좋지만 가장 좋은 구조는 trie입니다. GCC의 <ext/pb_ds/assoc_container.hpp>
에서 트라이를 얻을 수 있습니다. the online reference을 참조하십시오. 없는 순수한 set
만 map
-like 기능
#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;
}
가 제공된다. 위의 예제에서 나는 더미 데이터를 맵에 추가하기 위해 ... int
을 추가했다.
GCC 밖에서 작동하지 않는다면 어떤 상처를 입을까요? 한편
하는 비 - 표준 해시 테이블 (안std::
또는
ext::
무엇이든) 만 대신 단어 자체의 단어의 체크섬 중 검색 즉 대략 일치를 찾을 수있다. 그것은 가장 빠르고 가장 컴팩트 한 솔루션이 될 것입니다.
Bloom filters을 기반으로하는 사전에는 수 킬로바이트에 수천 단어가 포함될 수 있습니다.
어떻게 GCC 밖에서 작동하지 않습니까? 이러한 라이브러리를 Visual Studio (CL 컴파일러)로 가져 오는 방법은 없습니다. –
@YechielLabunskiy 파일은 단순히 GCC에 포함되어 있습니다. MSVC가 GCC 확장에 의존하지 않거나 MSVC 버그를 이동하지 않으면 MSVC에서 작동 할 수 있습니다. 확실히 한 번 사용해 볼 가치가 있습니다. 별도의 제 3 자 라이브러리로 취급하고 업데이트를 모니터링해야합니다. – Potatoswatter
독자적인 솔루션을 구형하고 사전이 수정되어있는 경우 perfect hash은 좋은 방법입니다. 상수 조회 시간을 보장합니다.
1 년이나 2 년 전 정확한 문제 (고정 사전 생성)가 있었고 완벽한 해싱이 실제적으로 2 계층 데이터 구조를 필요로하므로 조회마다 여러 메모리 읽기가 필요하다는 사실에 실망했습니다. 그것은 체인이있는 일반 오래된 해시 테이블보다 느리게 끝납니다. –
FWIW, 테이블 생성을 위해 작성한 코드는 다음과 같습니다. http://hg.mozilla.org/tracemonkey/file/e555673c8119/js/src/xpconnect/src/qsgen.py#l1488 코드 : http : //hg.mozilla.org/tracemonkey/file/e555673c8119/js/src/xpconnect/src/xpcquickstubs.cpp#l70 실제로는 3 개의 엔트리를 생성합니다 (몇 개의 룩업은 모든 체인을 걸어야합니다) . –
트라이를 사용하는 것이 좋습니다. Trie는 빠른 검색 및 예, 자동 완성을 사용하여 메모리 효율적인 사전을 작성하는 데 적합한 데이터 구조입니다.
해시 테이블로 생각하면 키 - 값 쌍 (또는 키 조회)을 빠르게 검색 할 수 있지만 해시 테이블과 달리 정렬 된 순서로 키를 반복 할 수 있습니다.
자세한 내용은/Trie - Wiki을 참조하십시오.
지도, 세트 등과 같이 표준 라이브러리에서 제공하는 C++ DS가 있으므로 문자열을 검색하는 데 가장 적합한 DS입니다. 나는 모든 문자열을 읽고 검색 할 것이다. – brett