【问题标题】:C++: Using map to sort and print the value of a string occurrences in a text fileC++:使用 map 对文本文件中出现的字符串的值进行排序和打印
【发布时间】:2014-12-05 00:55:09
【问题描述】:

好的,伙计们,我正在尝试自学如何使用地图。我的意图是打开一个 txt 文件并计算所有这些单词,然后显示特定单词出现的次数。然后(如果可能的话)我想在第二个映射中使用第一个映射来调用这些值,并且只输出出现的前 10 个(或 20 个或其他)频繁单词并打印次数(从最大到最小)它与实际单词一起出现。

我已经弄清楚如何输出所有单词以及它们出现的次数。而且我认为 map 已经对我在其中调用的实际字符串进行了自动排序,这很酷。我的问题是我需要对这些值进行排序,而不是字符串。

我已经对代码的特定功能进行了 cmets,但我只是不确定其他地图。

我只是寻求不同的想法。请不要刻薄。

**有人向我提到了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");
  }

【问题讨论】:

  • 我认为这种方法会使你的生活变得复杂 :) 你可以使用 map int -> 字符串,但是你如何处理关系呢?如果两个单词有相同的数字,它们会互相覆盖;你可以有一个地图 > ,并添加到集合中,但是你的代码变得更加复杂(它需要是,因为与领带,可能有相同频率的 11 个单词,所以有没有前 10 名)。优先级队列是有意义的,或者只是 的向量并按频率排序 ...

标签: c++ sorting map priority-queue


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可以如下创建一个新的地图容器

    std:map<int,string> count_word
    

    并将现有地图中的对插入到此。新地图会根据您的需要自行排序。

    这里的代码是sn-p。我没有编译。

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

    【讨论】:

    • 逻辑上看我想过这个,只是不知道在声明该映射后如何使用它按值排序。
    • 所以,我使用两个不同的 while 语句编译了 sn-p 两次不同的时间,它只对单词进行排序。我知道地图会自动执行此操作。如果可以对这些单词的值进行排序怎么办。
      示例“Zeta”出现“18”次
      “Tau”出现“12”次
      “Gamma”出现“9”次.....等等
    • map 包含 对。第一个映射的值是第二个映射的键。 std::map 仅按键排序。请使用您的最新更改更新代码。
    • 在 system("pause") 之前添加我的代码 sn-p 中的最后一个 while 循环块;
    • 当我最初尝试这样做时,最后一个 while 语句不会让 != 工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2014-05-18
    • 2020-04-10
    • 2019-05-03
    • 2018-04-02
    相关资源
    最近更新 更多