Как написать алгоритм, который узнает, в каких строках появляется конкретное слово (я использую std :: map) - PullRequest
0 голосов
/ 27 мая 2019

Я пишу код, который подсчитывает, сколько раз каждое слово появляется в тексте (я это задание), но я не могу найти способ вычислить, в каких строках эти слова появились.

Я не знаюЯ не знаю, с чего начать.


#include "header.h"
int main()
{
     //read the input, keeping track of each word and how often we see it
     std::ifstream in("tekstas.txt"); // input file

    std::string input;
    std::map<std::string, int> counters; // store each word and an associated counter
    std::vector<char>CharVect; // vector that stores symbols i want to replace
    formuojuChar(CharVect); // pushbacking that vector with symbols
     for (unsigned int i = 0; !in.eof(); i++)
    {
        std::getline(in, input);
        std::transform(input.begin(), input.end(), input.begin(), ::tolower); // lowering letters so for example "Mom"= "mom"
        Replace(input,CharVect, ' '); // replace symbols with space
        std::stringstream read(input);
        std::string word;
        while (read >> word)
        {
            ++counters[word];
        }
     }
     std::ofstream out("isvestis.txt");
    std::cout<<"Words that appear more than once in the text: "<<std::endl;
    std::cout<<std::endl;
     for (std::map<std::string, int>::const_iterator it = counters.begin();it != counters.end(); ++it)
        {
            if((it->second)>1)
            {

                std::cout<<"'" <<it->first<<"' " <<"appears "<<it->second <<" times in lines: " ;
                /*
                 ANY IDEAS ?
                 */
                std::cout<<std::endl;

            }
        }
        return 0;

}


Я ожидаю, что вывод покажет мне, в каких строках .txt появляется это слово.TY

Ответы [ 2 ]

1 голос
/ 27 мая 2019

Это похоже на учебное упражнение, которое вы хотите выполнить самостоятельно, и у меня есть политика не писать код для них.

Тем не менее, вы могли бы подсчитать количество переводимых вами строк.Вы столкнулись (которая сообщает вам строку, на которой вы находитесь), и всякий раз, когда вы видите текст, который ищете, вставьте номер текущей строки в std::set<unsigned> или std::vector<unsigned>.

.хочу сделать это в одном цикле, возможно, читая в строке за раз.Везде, где вы встречаете поисковый запрос, обновите счетчик слов и набор номеров строк.

0 голосов
/ 27 мая 2019

Основная проблема в вашем подходе заключается в том, что вы используете второй цикл для сбора информации о словах, и при этом вы потеряли всю информацию о том, в каких строках слова.

Вместо того, чтобы пытаться выяснить, на какой линии вы находитесь во втором цикле, у вас есть вся информация, необходимая для текущей строки в первом цикле.Все, что вам нужно, это переменная, которая отслеживает каждую строку.Вы используете (неправильно я могу добавить) std::getline - каждый раз, когда вы вызываете эту функцию, вы переходите на следующую строку, поэтому вы неявно знаете, на какой строке вы находитесь в первом цикле.


Во-первых, вам нужно исправить цикл чтения так, чтобы он правильно читал строки из файла:

std::string line;
while (std::getline(in, line))
{
//...
}

Во-вторых, внутри цикла while вы можете определить всю информациювам нужно слово, количество слов и строки, где слово найдено.Для этого вам не нужны два цикла.

Вместо std::map<std::string, int>, который знает только количество слов, вы можете создать карту, содержащую всю информацию - количество слов и строка (и), в которой найдено слово.Вот тип карты, который может содержать эту информацию:

std::map<std::string, std::pair<int, std::set<int>>>

«Вторая» карты содержит информацию о счете, и std::set, который будет содержать всеномера строк, где слово найдено.Причина std::set состоит в том, чтобы гарантировать, что повторяющиеся номера строк не будут сохранены.

Собирая все это вместе, вот пример программы, использующей этот тип:

#include <map>
#include <set>
#include <string>
#include <sstream>
#include <iostream>

// pair and map type
using WordInfo = std::pair<int, std::set<int>>;
using WordMap = std::map<std::string, WordInfo>;

int main()
{
    // our map
    WordMap wm;
    std::string line;

    // the line count
    int line_number = 1;
    while (std::getline(std::cin, line))
    {
        // line parser
        std::istringstream strm(line);
        std::string word;
        while ( strm >> word)
        {
            // we call map::insert, not `[ ]` to insert into a map
            auto pr = wm.insert({word, {0,std::set<int>()}});

            // the return value of map::insert gives us a pair, where the first is 
            // an iterator to the item in the map
            auto& mapIter = pr.first;

            // increment the word count   
            ++(mapIter->second.first);

            // insert the line number into the set
            mapIter->second.second.insert(line_number);
        }

        // increment the line counter
        ++line_number;
    }

    // output results
    for (auto& m : wm )
    {
        std::cout << "The word  \"" << m.first << "\" appears " << m.second.first << " times on the following lines:\n";
        for ( auto& m2 : m.second.second)
            std::cout << m2 << " ";
        std::cout << "\n\n";
    }
}

Так чтобыло сделано здесь?

1) Строка, в которой включено каждое слово, известна в цикле чтения.Все, что нужно сделать, это увеличить счетчик строк для каждой строки, которая читается.

2) Мы используем std::map::insert, чтобы вставить запись в карту, а не std::map::operator[ ],Причина в том, что map::insert не будет вставлять запись, если запись уже существует, она будет вставлять новую запись, если запись не существует, и независимо от того, что сделано, std::map::insert возвращает итератор для элемента вкарта.

Нам понадобится возвращенный нам итератор для дальнейшей обработки.В последующих строках мы просто увеличиваем счет и обновляем std::set.

Вот живой пример .


Примечание: я понятия не имеючто все заменители вы делаете в своей исходной программе, поэтому я пропустил все это и сконцентрировался исключительно на задаче определения слов и строки (ий) слов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...