读取文本文件并在 C++ 中按行返回字数

Reading a text file and returning the word count by line in C++

我们开始在我的编程中从 C 转向 C++ class,我们当前的实验室作业是创建一个程序,给定文本文件读取其内容,然后 returns 一个列表文件中单词的数量以及它们出现的行号以及该单词在每行中出现的次数,格式为 Word Line:Count.

Foo bar bar
Baz
Foo
<EOF>

哪个应该 return:

Foo  1:1 3:1
Bar  1:2
Baz  2:1

到目前为止,我们唯一涵盖的数据结构是地图,我们用它编写了以下程序,输出总字数

int main(int argc, const char*argv[]) {
    map<string, unsigned int> table;
    string word;

    while (cin >> word) {
        ++table[word];
    }

    for (std::map<string, unsigned int>::iterator itr = table.begin();
            itr != table.end(); ++itr) {
        cout << itr->first << "\t" << itr->second << endl;
    }

    return 0;
}

我们被告知可以(稍微)修改此程序以使其打印出行号和字数。我的问题是,有没有办法使用地图为每个键设置 2 个值?或者有没有更好的方法来实现这样的东西?

您可以让地图将大部分内容存储为键值。要能够计算单词出现的次数并保留它出现的行号的动态列表,您可以执行以下操作。这是我想到的最简单直接的解决方案,它不是最有效的。

使用带有字符串键和值向量的映射来存储,index = WordLine, value at index = Count

#include <vector>       // std::vector

using namespace std;
map<string, vector<int>> words;

当您遇到单词时,在地图中查找它们并增加 line_num 索引处的向量以表示它在该行中出现的次数。

#include <sstream>
using namespace std;

string line;
string word;
int line_num = 0;
while (getline(cin, line)) {
    istringstream words_iss(line); 
    while(line >> word) {
        ++words.at(word)[line_num];
    }
    ++line_num;
}

效率低下是因为使用索引来表示行号,因为该词可能要到第 n 行才会出现。但是,当它将它放在索引 n 处的向量中时,它将为向量分配 space 0 - (n-1) 整数。同样在打印中,您必须检查向量中的每个值以查看它是否不为 0。

您可以通过遍历映射中的每个字符串,然后遍历每个键的向量并仅在索引处的值不为 0 时打印来打印。

如评论中所述,另一种解决方案是使用

map<string, map<int, int>> 

同理。对于大多数情况,这会更有效。