2014-12-05 53 views
0

好吧,我試圖教自己如何使用地圖。我的意圖是打開一個txt文件並計算所有這些單詞,然後顯示特定單詞出現的次數。然後(如果它可能)我想在第二張地圖中使用第一張地圖來調用這些值,並只輸出出現的前10位(或20位或任何)頻繁詞並打印次數(從最大到最小)它與真實的單詞一起出現。C++:使用地圖來排序和打印文本文件中字符串出現的值

我已經想出瞭如何輸出所有單詞以及它們出現的次數。我認爲地圖已經很好地排列了我自動調用的實際字符串。我的問題是,我需要這些值排序,而不是字符串。

我已經對代碼的特定功能發表了評論,但我不確定這個其他地圖。

我只是尋求不同的想法。請不要吝嗇。

**有人向我提到了priority_queue,但這對我來說也是新的。如果你可以用一個更加口頭的方式來解釋這個例子,這樣我就可以理解,那會很棒!

#include <iostream> 
#include <map> 
#include <fstream> 
#include <string> 

using namespace std; 

//makes word count a declaration 
//makes count word a declaration 
typedef map <string, int> word_count; 
typedef map <int, string> count_word; 


int main() 
{ 
word_count word_count; 
string filename; 


// Get the filename. 
cout << "enter data.txt "; 
cin >> filename; 

// Open file. 
ifstream file(filename.c_str()); 

// Read in all the words. 
string word; 
while (file >> word) 
{ 
    // Remove punctuation. 
    int index; 
    while ((index = word.find_first_of(".,!?\\;-*+[]<>() '")) != string::npos) 
    { 
     word.erase(index, 1); 
    } 

    ++word_count[word]; 
} 


std::map <int, string> count_word; 

// Print out the first 10 words counts. 
word_count::const_iterator current(word_count.begin()); 


int count = 0; 
while (current != word_count.end() && count<10) 
{ 

    count++; 
    cout << "The word '" << current->first << "'  appears " << current->second << " times" << endl; 
    count_word.insert(std::pair<int, string>(current->second, current->first)); 
    ++current; 

} 


count_word::const_iterator new_current(count_word.begin()); 
count = 0; 

while (new_current != count_word.end() && count<10) 
{ 

    count++; 
    cout << new_current -> first << " times appears the word '" << 
      current -> second << endl; 
    ++new_current; 
} 

system("pause"); 
    } 
+0

我認爲這種方法使你的生活複雜:)你可以有地圖int - >字符串,但那麼你如何處理關係?如果兩個單詞有相同的數字,他們會相互覆蓋;你可以有一個映射>,並添加到集合中,但是隨後你的代碼變得更加複雜(它需要這樣做,因爲綁定可能會有11個單詞具有相同的頻率,所以沒有頂部10)。優先級隊列是有意義的,或者只是一個向量並按頻率排序... – okaram 2014-12-05 01:09:44

回答

0

您可以創建一個新的地圖容器如下

std:map<int,string> count_word 

,並從現有地圖這一插入對。新地圖會自行排序。

這裏的代碼片斷我沒有編譯。

std:map<int,string> count_word; 
word_count::const_iterator current(word_count.begin()); 


int count = 0; 
while (current != word_count.end() && count<10) 
{ 

    count++; 
    cout << "The word '" << current -> first << "'  appears " << current -> second << " times" << endl; 
    count_word.insert(std::pair<int,string>(current->second,current->first); 
    ++current; 

} 

count_word::const_iterator new_current(count_word.begin()); 
//for(auto &x:count_word) 
//std::cout<<x->first<<"no of times"<< x->second << "word"<<endl; 
//Either you can use above 2 line to print or below given few lines 
while (new_current != word_count.end() && count<10) 
{ 

    count++; 
    cout << new_current -> first << " times appears the word '" <<<< current -> second << endl; 
    ++new_current; 
} 
+0

從邏輯上看,我想到了這一點,只是不知道如何使用它在聲明後按值排序。 – 2014-12-05 01:39:55

+0

@RishabhPatel我添加了代碼片段 – Steephen 2014-12-05 01:57:44

+0

因此,我使用兩個不同的while語句編譯了片段兩個不同的時間段,並且它只對這些單詞進行排序。我明白,地圖自動做到這一點。如果這些單詞的價值可以排序,會怎樣?


示例「Zeta」出現「18」次
「Tau」出現「12」次
「Gamma」出現「9」次.....等 – 2014-12-05 02:32:33

0

一個priority queue允許設置,你可以使用你的優勢自定義的比較,通過比較計數(映射值)您的隊列可以通過值進行排序(map也可以用一個比較,但它僅適用於鍵):

typedef pair<string,int> str_to_int; // = word_count::value_type 
struct Compare { 
    bool operator()(const str_to_int & a, const str_to_int & b) { 
     return a.second < b.second; 
    } 
}; 
// ... 
priority_queue<str_to_int, vector<str_to_int>, Compare> queue(word_count.begin(), word_count.end()); 
// Print the top 10 
for (int i=0; i<10; ++i) { 
    const str_to_int & e = queue.top(); 
    queue.pop(); 
    cout << "The word '" << e.first << "'  appears " << e.second << " times" << endl; 
} 
相關問題