C++ 如何编写一个算法,找出特定单词出现在哪行(我使用的是std::map)

C++ 如何编写一个算法,找出特定单词出现在哪行(我使用的是std::map),c++,c++11,C++,C++11,我正在编写代码来计算每个单词在文本中出现的次数(我完成了这个任务),但我找不到一种方法来计算这些单词出现在哪行 我不知道从哪里开始 #包括“header.h” int main() { //阅读输入,跟踪每个单词以及我们看到它的频率 std::ifstream in(“tekstas.txt”);//输入文件 std::字符串输入; 映射计数器;//存储每个单词和关联的计数器 std::vectorCharVect;//存储要替换的符号的向量 formuojuChar(CharVect);//

我正在编写代码来计算每个单词在文本中出现的次数(我完成了这个任务),但我找不到一种方法来计算这些单词出现在哪行

我不知道从哪里开始


#包括“header.h”
int main()
{
//阅读输入,跟踪每个单词以及我们看到它的频率
std::ifstream in(“tekstas.txt”);//输入文件
std::字符串输入;
映射计数器;//存储每个单词和关联的计数器
std::vectorCharVect;//存储要替换的符号的向量
formuojuChar(CharVect);//用符号推送该向量
对于(无符号整数i=0;!in.eof();i++)
{
std::getline(输入,输入);
std::transform(input.begin(),input.end(),input.begin(),::tolower);//降低字母,例如“Mom”=“Mom”
替换(输入,CharVect“”);//用空格替换符号
std::stringstream读取(输入);
字符串字;
while(阅读>>word)
{
++计数器[字];
}
}
std::of Stream out(“isvestis.txt”);

std::cout这看起来像是一个你想自己做的学习练习,我有一个不为这些编写代码的策略

但是,您可以做的一件事是计算遇到的换行数(这会告诉您正在搜索的行),并且每当您看到正在搜索的文本时,将当前行号插入
std::set
std::vector


您可能希望在单个循环中执行此操作,或者一次读取一行。当您遇到搜索词时,请同时更新单词计数器和行号集。

此方法的主要问题是,您正在使用第二个循环来收集有关单词的信息,而这样做会丢失所有关于ut单词在哪一行

在第一个循环中,您拥有当前行所需的所有信息,而不是试图找出第二个循环中的哪一行。您所需要的只是一个跟踪每一行的变量。您正在使用(我可能会添加错误),
std::getline
——每次调用该函数时,都会转到下一行,这样就可以隐式地知道第一个循环中的行


首先,您需要修复读取循环,以便它能够正确读取文件中的行:

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

第二,在
while
循环中,您可以确定单词、单词计数和单词所在行所需的所有信息,而不需要两个循环

您可以创建一个包含所有信息的映射,而不是只知道字数的
std::map
,即字数和字数所在的行。下面是一个可以包含这些信息的映射类型:

std::map

映射的“第二个”保存有关计数的信息,以及一个
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";
    }
}
#包括
#包括
#包括
#包括
#包括
//配对和映射类型
使用WordInfo=std::pair;
使用WordMap=std::map;
int main()
{
//我们的地图
文字映射;
std::字符串行;
//行数
int line_number=1;
while(std::getline(std::cin,line))
{
//行分析器
std::istringstream strm(线路);
字符串字;
while(strm>>word)
{
//我们调用map::insert,而不是“[]”来插入到映射中
auto pr=wm.insert({word,{0,std::set()}});
//map::insert的返回值为我们提供了一对,其中第一个是
//映射中项目的迭代器
自动&mapIter=pr.first;
//增加字数
++(mapIter->second.first);
//将行号插入集合中
mapIter->second.second.insert(行号);
}
//增加行计数器
++线号;
}
//输出结果
用于(自动和维护:wm)
{

std::cout
std::map
——这可能是不够的信息。您可以使用类似于
std::map
的方法来存储单词的全部信息。第一个是单词,第二个是包含单词计数和存储单词所在行的向量的对。更好的是,
std::map
,以便
设置
不会存储重复的行号。另外,
Replace
有什么功能?为什么不直接调用
std::Replace
?此外,您可以在第一个循环中收集所有这些信息。不需要两个循环。
for(unsigned int i=0;!In.eof();i++)
--我认为您应该了解如何读取文件中的一行数据的基本知识。这不是读取数据的方法--一个简单的
while(std::getline(in,line))
就是你所需要的。谢谢你的回答。但问题是我找不到知道我在哪一行的方法。也许有什么想法?@oskarasdiratis你知道你在第一个循环中在哪一行。这就是为什么你应该尝试使用一个循环而不是两个循环来解决问题。