我是一名C++初学者。有人能告诉我在C++中用于存储字典中所有单词并查找单词是否存在的最佳数据结构吗?我知道哈希表是最好的选择,但我不知道哪种数据结构使用它们?
非常感谢您的帮助。
非常感谢您的帮助。
unordered_set
或hash_set
。它们本质上是相同的;前者是即将发布的C++0x标准的一部分,并受到一些最新编译器的支持,后者来自原始的SGI STL,并包含在许多标准库实现中。hash_set
: 官方的?没有。但是许多标准库的实现(包括Visual C++和libstdc++)都包括它。 unordered_set
:目前还没有。当C++0x在2011年获批时,它将成为标准库的一部分。一些标准库的实现(例如Visual C++ 2010库)包括它。 - James McNellishash_map
(有关详细信息请参见我指向的维基百科条目)--当然,如果从我的答案中不清楚的话,还提供了hash_set
。如果你需要在任何符合标准的C++上运行而没有添加组件/库,则std::map
(或者如果你仅仅想要存在/不存在信息,而没有每个单词的辅助数据,则使用std::set
)是唯一的选择,但这不是一个哈希映射[或集合;-)]。旧的(仍然当前)C++标准中没有哈希数据结构。 - Alex Martelli哈希表很不错,但最好的数据结构是trie(字典树)。你可以从GCC的<ext/pb_ds/assoc_container.hpp>
获取trie。详见在线参考资料。
#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;
}
仅提供类似于map
的功能,而不是纯粹的set
。在上面的示例中,我添加了一个虚拟的int
作为要映射到的数据……这不会对其造成太大的影响。
真正有问题的是,在GCC之外这样做行不通。
另一方面,一种非标准哈希表(不是std::
或ext::
等)将允许您仅查找近似匹配,即在单词的校验和之间搜索而不是单词本身。这将是最快,最紧凑的解决方案。基于Bloom过滤器的字典可以在几千字节内包含许多单词。
哈希表,如果你的C++编译器库中有它(例如GNU C++或Microsoft Visual C++)。 如果你使用其他不太常见的编译器,我猜你仍然可以找到一个不错的第三方实现hash_map
。
即将发布的C++标准将把这个数据结构称为std::unordered_map
。
如果你不想在字典中与任何单词关联信息,只需记录单词是否存在,你可以使用上述数据结构类型的_set
(而不是_map
)变体。
当然,它们都是模板(就像C++标准库中的所有容器一样),所以您需要使用典型的模板语法来实例化它们。
hash_set
或unordered_set
就足够了——如果他需要记录任何辅助信息,那么..._map
变体将更好(并且同样有效)。 - Alex Martelli如果你愿意自己动手解决问题,并且你的字典是固定的,那么完美哈希是一个不错的选择。它保证了常数级别的查找时间。