- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我需要在文本中找到大约 25 000 个单词。为此目的最合适的算法/库是什么?
目标语言是 C++
最佳答案
I once used the Boyer-Moore algorithm and it was quite fast.
Boyer-Moore 不适合高效地搜索多个单词。实际上有一种非常有效的算法可以做到这一点,称为 Wu-Manber 算法。我将发布一个引用实现。但是请注意,我前段时间这样做只是为了教育目的。因此,该实现并不适合直接使用,而且还可以提高效率。
它还使用 Dinkumware STL 中的 stdext::hash_map
。替换为 std::tr1::unordered_map
或适当的实现。
在 lecture script 中有对该算法的解释。摘自 Knut Reinert 在柏林自由大学举办的一场讲座。
original paper也在网上(刚刚又找到了),但我不是特别喜欢那里提供的伪代码。
#ifndef FINDER_HPP
#define FINDER_HPP
#include <string>
namespace thru { namespace matching {
class Finder {
public:
virtual bool find() = 0;
virtual std::size_t position() const = 0;
virtual ~Finder() = 0;
protected:
static size_t code_from_chr(char c) {
return static_cast<size_t>(static_cast<unsigned char>(c));
}
};
inline Finder::~Finder() { }
} } // namespace thru::matching
#endif // !defined(FINDER_HPP)
#include <vector>
#include <hash_map>
#include "finder.hpp"
#ifndef WUMANBER_HPP
#define WUMANBER_HPP
namespace thru { namespace matching {
class WuManberFinder : public Finder {
public:
WuManberFinder(std::string const& text, std::vector<std::string> const& patterns);
bool find();
std::size_t position() const;
std::size_t pattern_index() const;
private:
template <typename K, typename V>
struct HashMap {
typedef stdext::hash_map<K, V> Type;
};
typedef HashMap<std::string, std::size_t>::Type shift_type;
typedef HashMap<std::string, std::vector<std::size_t> >::Type hash_type;
std::string const& m_text;
std::vector<std::string> const& m_patterns;
shift_type m_shift;
hash_type m_hash;
std::size_t m_pos;
std::size_t m_find_pos;
std::size_t m_find_pattern_index;
std::size_t m_lmin;
std::size_t m_lmax;
std::size_t m_B;
};
} } // namespace thru::matching
#endif // !defined(WUMANBER_HPP)
#include <cmath>
#include <iostream>
#include "wumanber.hpp"
using namespace std;
namespace thru { namespace matching {
WuManberFinder::WuManberFinder(string const& text, vector<string> const& patterns)
: m_text(text)
, m_patterns(patterns)
, m_shift()
, m_hash()
, m_pos()
, m_find_pos(0)
, m_find_pattern_index(0)
, m_lmin(m_patterns[0].size())
, m_lmax(m_patterns[0].size())
, m_B()
{
for (size_t i = 0; i < m_patterns.size(); ++i) {
if (m_patterns[i].size() < m_lmin)
m_lmin = m_patterns[i].size();
else if (m_patterns[i].size() > m_lmax)
m_lmax = m_patterns[i].size();
}
m_pos = m_lmin;
m_B = static_cast<size_t>(ceil(log(2.0 * m_lmin * m_patterns.size()) / log(256.0)));
for (size_t i = 0; i < m_patterns.size(); ++i)
m_hash[m_patterns[i].substr(m_patterns[i].size() - m_B)].push_back(i);
for (size_t i = 0; i < m_patterns.size(); ++i) {
for (size_t j = 0; j < m_patterns[i].size() - m_B + 1; ++j) {
string bgram = m_patterns[i].substr(j, m_B);
size_t pos = m_patterns[i].size() - j - m_B;
shift_type::iterator old = m_shift.find(bgram);
if (old == m_shift.end())
m_shift[bgram] = pos;
else
old->second = min(old->second, pos);
}
}
}
bool WuManberFinder::find() {
while (m_pos <= m_text.size()) {
string bgram = m_text.substr(m_pos - m_B, m_B);
shift_type::iterator i = m_shift.find(bgram);
if (i == m_shift.end())
m_pos += m_lmin - m_B + 1;
else {
if (i->second == 0) {
vector<size_t>& list = m_hash[bgram];
// Verify all patterns in list against the text.
++m_pos;
for (size_t j = 0; j < list.size(); ++j) {
string const& str = m_patterns[list[j]];
m_find_pos = m_pos - str.size() - 1;
size_t k = 0;
for (; k < str.size(); ++k)
if (str[k] != m_text[m_find_pos + k])
break;
if (k == str.size()) {
m_find_pattern_index = list[j];
return true;
}
}
}
else
m_pos += i->second;
}
}
return false;
}
size_t WuManberFinder::position() const {
return m_find_pos;
}
size_t WuManberFinder::pattern_index() const {
return m_find_pattern_index;
}
} } // namespace thru::matching
vector<string> patterns;
patterns.push_back("announce");
patterns.push_back("annual");
patterns.push_back("annually");
WuManberFinder wmf("CPM_annual_conference_announce", patterns);
while (wmf.find())
cout << "Pattern \"" << patterns[wmf.pattern_index()] <<
"\" found at position " << wmf.position() << endl;
关于c++ - 在文本中搜索 25 000 个单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/154365/
我有以下数据框 (df_hvl),列名“FzListe”和以下数据: FzListe 7MA1, 7OS1 7MA1, 7ZJB 7MA2, 7MA3, 7OS1 76G1, 7MA1, 7OS1 7
我有点小问题。仅当尝试写入的相同字符串/单词不存在时,我才想写入文件。在我的例子中,它是一个 IP 地址和端口,用“:”分隔。如果我手动写入文件,例如 193...:80 和 193...:22,它指
如何返回结果列中的单词示例? 我得到的最接近的是 [\W]{2,}[^,\W].+[?=,] ID 文本 我的结果(完全匹配) 预期(完全匹配) 1 词A,世界B,词C , 世界 B, 字B 2 wo
我想在引号之间得到一个字符串 我知道一个解决方案是: /'.*?'/ 但问题是它不适用于英语中的所有格或收缩格 例如: What is the name of Mario's brother in t
我应该在句子中找到出现最多的单词。 这是我尝试过的,但不起作用。 '); $max = -1; $resultWords = array(); $resultCount = array(); $i =
我是vim的新手。我正在尝试练习(最近阅读了一些教程),但是我发现我不能不突出显示“复制粘贴”中的字符/单词/行。 在Textmate中,我通常使用SHIFT + CTRL + LeftArrowKe
有谁知道一个JSON格式的英语词典,该词典具有(单词,定义和单词类型,例如名词/形容词/动词/副词) 这种格式: [ {"Word" : "Chair", "Definition" : "A
我正在做一些 javascript,同时我注意到我无法替换 html 标记内的“ document.getElementById('label').innerHTML = document.get
您好,我正在使用 groovy 2.1.5,我必须编写一个代码来显示具有给定路径的目录的内容/文件,然后它会备份文件并替换文件中的单词/字符串。 这是我用来尝试替换所选文件中的单词的代码 String
我正在准备一个实验,我想使用python编写程序以识别参与者说出的某些单词。 我在python中搜索了很多有关语音识别的内容,但结果却很复杂(例如CMUSphinx)。 我要实现的是一个程序,该程序接
假设我有以下代码: $size = 23.9 $size = "$size GB" write $size 我想在其他事情上使用相同的变量,即 if ($size -lt 20) {...} 这显然是
我想替换字符串中单词 Date 的所有情况,除非它是 Date()(即 Date 后跟括号)。这是一个字符串示例以及我最初尝试的内容: x gsub("Date", paste("Date:", S
我对 Java 和编程都很陌生,请记住这一点,请不要对我严厉 ^^。接下来,我最近用 Java 进行了一些培训,我喜欢这个挑战,但现在我只是陷入困境。我做了一些示例来查找用户输入的最大字符串,一切都很
我必须给一个数字x,并写x个字符串(单词)。我必须找到写得最多的那一篇。它可以工作,但是当我尝试从文件中读取它时,却没有。例如,如果我执行 a.out'' #include #include in
这里是学习者,如果这个问题看起来很荒谬,请多多包涵。假设我试图引用字符串中的字符而不是字符串本身,我该怎么做呢?我的意思是; 给定:var str = "我想知道一个大脑分散的计算机如何保持理智" 我
这是阿克沙塔。我一直在解析以下数据。我想单独获取每个单词。我可以有一个示例代码以便我可以继续吗 RTRV-HDR RH01 SIMULATOR 09-11-18 16 13 19 M R
我有一个任意字符串,它总是包含至少一个英文单词后跟一系列数字:"Hello World 1234" 我如何只提取 "Hello World" 来自字符串? 最佳答案 在我看来你需要反正则表达式: St
我正在尝试输入一个四个单词的句子,然后能够使用indexOf和子字符串单独打印出每个单词。有什么想法我做错了吗? 已编辑 那么这就是它应该的样子吗?我已经运行了两次,得到了两个不同的答案,所以我不确定
如何在文本开头查找短语(单词) 我需要非常快速的解决方案来查明文本是否以某些已知短语开头 我在 Mysql (innodb) 表中的短语如下: CREATE TABLE IF NOT EXISTS `
我在 MYSQL 表中有一本字典,该表由 240 000 个单词组成。例如,如果我有字母 G、I、G、S、N> 和 O 我想选择表中包含所有或部分这些字母(并且没有其他字母)的所有单词。 可接受的词语
我是一名优秀的程序员,十分优秀!