C ++: использование карты для сортировки и печати значения вхождения строки в текстовом файле

0

Хорошо, ребята, я пытаюсь научить себя, как использовать карту. Мои намерения состоят в том, чтобы открыть txt файл и подсчитать все эти слова, а затем указать, сколько раз происходит определенное слово. Затем (ЕСЛИ ЕГО ВОЗМОЖНО) я бы хотел использовать эту первую карту во второй карте, чтобы вызвать эти значения, и выводить только первые 10 (или 20 или любых) часто встречающихся слов и печатать количество раз (от самого большого до самого маленького) что это происходит вместе с фактическим словом.

Я уже понял, как выводить ВСЕ слова и сколько раз они происходят. И я думаю, что это довольно круто, что карта уже сортирует фактические строки, которые я вызывал внутри нее автоматически. Моя проблема в том, что мне нужны эти значения, а не строки.

Я комментировал конкретные функции кода, но я просто не уверен в этой другой карте.

Я ищу разные идеи. Пожалуйста, не будь скупой.

** Кто-то сказал мне о 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 -> string, но как вы справляетесь со связями? Если два слова имеют одинаковое число, они перекрывают друг друга; у вас может быть карта <int, set <string >> и добавление в набор, но тогда ваш код становится более сложным (что и должно быть, так как в случае связей может быть 11 слов с одинаковой частотой, поэтому есть нет топ 10). Приоритетная очередь имеет смысл, или просто вектор <word, freq> и сортировка по freq ...
Теги:
sorting
priority-queue
map

2 ответа

0

Очередь приоритетов позволяет настраивать пользовательский компаратор, который вы можете использовать в своих интересах, сравнивая подсчеты (значения карты), ваша очередь может быть отсортирована по значению (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;
}
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
    Смотрите логически, я думал об этом, только не знал точно, как использовать его для сортировки по значениям после объявления этой карты.
  • 0
    @RishabhPatel Я добавляю фрагмент кода
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню