这是我作为起点要做的事情(只是因为它简单快捷):
- 使用共享映射或 hash_map 将单词映射到数字
- 对于每个文本,构建相应的单词级三元组计数图
- 比较重叠
我们可以假设字典大小小于 1m(或 21 位),所以我们可以在 int64 中编码一个三元组。
void CountTrigrams(const vector<string>& words,
map<string, int> * dict,
map<int64, int> * result) {
int64 trigram = 0;
for (int i = 0; i < words.size(); i++) {
const& word = words[i];
int id;
auto di = dict->find(word);
if (di == dict->end()) {
id = dict.size();
dict[word] = id;
} else {
id = di->second;
}
trigram = ((trigram << 21) | id) & 0x7fffffffffffffff;
if (i > 2) {
auto ti = result->find(trigram);
if (ti == result->end()) {
result[trigram] = 1;
} else {
ti->second++;
}
}
}
}
然后比较每一对的结果:
int Compare(const map<int64, int> & t1, const map<int64, int> & t2) {
int score = 0;
for (auto i = t1.first(); i != t1.end(); i++) {
auto j = t2.find(t1->first);
if (j != t2.end()) {
score += MAX(i->second, j->second);
}
}
return score;
}
以某种方式标准化分数可能是有意义的,例如除以三元组的总数。