我有一个大文本文件,每行都有标记。我想计算每个令牌的出现次数并对其进行排序。我如何在 C++ 中有效地做到这一点,最好使用内置函数和最短的编码(当然也是最有效的)?我知道如何在 python 中执行此操作,但不确定如何在 STL 中使用 unordered_map 执行此操作。
问问题
309 次
2 回答
3
我会采用 unordered_map 方法。为了选择最频繁的 k 个标记,假设 k 小于标记的总数,您应该查看std::partial_sort。
顺便++frequency_map[token]
说一句,(例如,频率映射是std::unordered_map<std::string, long>
)在 C++ 中是完全可以接受的,尽管我认为 Python 中的等价物会在新出现的标记上爆炸。
好的,给你:
void most_frequent_k_tokens(istream& in, ostream& out, long k = 1) {
using mapT = std::unordered_map<string, long>;
using pairT = typename mapT::value_type;
mapT freq;
for (std::string token; in >> token; ) ++freq[token];
std::vector<pairT*> tmp;
for (auto& p : freq) tmp.push_back(&p);
auto lim = tmp.begin() + std::min<long>(k, tmp.size());
std::partial_sort(tmp.begin(), lim, tmp.end(),
[](pairT* a, pairT* b)->bool {
return a->second > b->second
|| (a->second == b->second && a->first < b->first);
});
for (auto it = tmp.begin(); it != lim; ++it)
out << (*it)->second << ' ' << (*it)->first << std::endl;
}
于 2012-10-05T02:02:10.030 回答
0
假设您知道如何从 C++ 文件中读取行,这应该是朝着正确方向的推动
std::string token = "token read from file";
std::unordered_map<std::string,int> map_of_tokens;
map_of_tokens[token] = map_of_tokens[token] + 1;
然后,您可以将它们打印出来(用于测试):
for ( auto i = map_of_tokens.begin(); i != map_of_tokens.end(); ++i ) {
std::cout << i->first << " : " << i->second << "\n";
}
于 2012-10-05T00:36:19.107 回答