在字典中查找单词模式,高性能
Finding word patterns in a dictionary, high performance
我需要建立某种字典,其中还包含每个单词在语言中出现的单词频率。通常,这将使用std::unordereded_map来实现,对吗?现在问题来了。。。我想找到所有符合某些正则表达式的单词及其频率,而性能是我最关心的问题。
我认为我将无法避免在一系列元素上迭代,并按元素检查它们是否匹配模式。因此,我认为使用一对矢量而不是地图可能是明智的:
using namespace std;
typedef vector<pair<string, double>> Dictionary
vector<Dictionary::const_iterator> index;
Dictionary dict;
...
for_each(index['d'], index['e'], DoSomething);
这将使我能够有效地迭代所有以"d"开头的单词。当然,只有当我已经知道正则表达式的第一个字母时,这才有帮助,我想这通常不会是这样。此外,如果我已经知道了整个单词,没有任何不确定性,只想查找它的频率,我就必须遍历整个部分,直到找到它。地图可以让我更快地查找它。例如,在查找单词"deer"时
Dictionary::const_iterator it =
find_if(index['d'], index['e'], [] // Lambda
(pair<string, double> const &pr)
{
return pr.first == "deer";
});
一点也不优化!一个解决方案可能是针对不同的情况使用不同的字典实现,尽管内存不是什么大问题,但这似乎是一个愚蠢的变通方法。
有什么建议吗?
按照您的想法std::vector<std::pair<boost::regex, int> >
可能是效率最高;你反复尝试寻找匹配项。
如果你愿意做这项工作,一个更好的解决方案会实现您自己的正则表达式类,而不需要捕获(大多数正则表达式中的(...)
运算符)。在没有捕获的情况下,转换正则表达式相当容易表达式转换为纯DFA,和可以或正则表达式,每个正则表达式返回不同的接受代码。(这是我自己的正则表达式类作品对于大多数应用程序来说,它的灵活性远不如Boost,因为它不支持捕获。但确实如此允许以下内容:
RegularExpression t1( expr1", 0 );
RegularExpression t2( expr2", 1 );
// ...
RegularExpression t = t1 | t2 /* | t3 | t4 | ... */ ;
匹配时,如果expr1匹配,它将返回0,如果expr2匹配,则返回1比赛等。;然后,您可以使用匹配id作为索引int的向量。(如果没有匹配,则返回-1。)
通过这种方式,搜索时间相对于输入的长度。不管表达式的数量你正在努力匹配。(我的RegularExpression类设计于20多年前,用于生成编译器前端。大约15年前,我将其重新命名为输入。)
多年来,该代码一直可以在网上找到,但我没有现在有一个网页,所以除非有人保留了一个旧的复制,它不是。我很乐意寄给你,但是警告说图书馆已经有一段时间没有维护了,所以让它用现代的编译器。(它最初是用预标准C++编写的,并且仍然包含许多使其编译的解决方法像Sun CC 4.x这样的东西)
您的最佳选择是使用Finite Satae Transducerhttp://www.ims.uni-stuttgart.de/projekte/gramotron/SOFTWARE/SFST.html。
正如你所说,这张地图会占用很多空间。
您可以将转换器视为一个大型正则表达式(regex是一个编译的自动机)。
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 此模式的C++RegEx
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 使用可变模板的Broadcaster/Listener模式
- c++方法参数只能在linux的发布模式下自行更改
- 资源管理设计模式
- 使用 mod_gsoap 部署服务时,如何在 Gsoap 中更改 soap 上下文的模式?
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 小字符串优化(调试与发布模式)
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 在C++的一系列数字中查找重复模式
- 是否允许使用带有"w+"模式的 freopen 进行标准设置?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- 在字典中查找单词模式,高性能
- 用于结构化对象的高性能装饰器模式