2012-10-05 97 views
2

我在每一行中都有一個帶有標記的大文本文件。我想計算每個令牌的出現次數並對其進行排序。如何在C++中高效地使用內置函數和最短編碼(當然最有效)?我知道如何在python中做到這一點,但不知道如何在STL中使用unordered_map來做到這一點。使用C/STL計算出現次數並打印頂部K

+0

@ildjarn正如我所說,我能夠指望使用unordered_map標記的出現。現在我想要高效而優雅地找到頂級K(我自己實現排序算法的時間很短)。 – ElKamina

+0

向我們展示您嘗試過的_code_。 – ildjarn

回答

3

我會採用unordered_map方法。爲了選擇最頻繁的k令牌,假設k小於令牌的總數,你應該看看std::partial_sort

順便說一句,++frequency_map[token](其中frequency_map是,比如std::unordered_map<std::string, long>)在C++中是完全可以接受的,但我認爲Python中的等價物會炸燬新觀察到的標記。

OK,在這裏你去:

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; 
} 
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"; 
}