在我的编程课上,我们开始从 C 转向 C++,我们当前的实验室作业是创建一个程序,给定一个文本文件,读取其内容,然后返回文件中的单词列表以及行它们出现的次数以及该词在每行中出现的次数,格式为 Word Line:Count。
Foo bar bar
Baz
Foo
<EOF>
应该返回:
Foo 1:1 3:1
Bar 1:2
Baz 2:1
到目前为止,我们唯一涉及的数据结构是 map ,我们用它编写了以下输出总字数的程序
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;
}
我们被告知可以(稍微)修改此程序以使其打印出行号和字数。我的问题是,有没有办法使用 map 为每个键设置 2 个值?或者有更好的方法来实现这样的事情吗?
最佳答案
您可以让您的 map 将大部分内容存储为键值。要能够计算单词出现的次数并保留它出现的行号的动态列表,您可以执行以下操作。这是我想到的最简单直接的解决方案,它不是最有效的。
使用带有字符串键值 vector 的map来存储,index = WordLine,value at index = Count
#include <vector> // std::vector
using namespace std;
map<string, vector<int>> words;
当您遇到单词时,在 map 中查找它们并增加 line_num 索引处的 vector 以表示它在该行中出现的次数。
#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 处的 vector 中时,它将为 vector 分配 0 - (n-1) 整数空间。同样在打印时,您必须检查 vector 中的每个值以查看它是否不为 0。
您可以通过循环遍历映射中的每个字符串,然后循环遍历每个键的 vector 并仅在索引处的值不为 0 时打印。
如评论中所述,另一种解决方案是使用
map<string, map<int, int>>
类似的逻辑。对于大多数情况,这会更有效。
关于c++ - 读取文本文件并在 C++ 中按行返回字数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29618503/