读取文本文件并在C ++中逐行返回单词

时间:2015-04-14 03:10:01

标签: c++ dictionary word-count line-numbers

我们开始在编程类中从C转到C ++,而我们当前的实验室分配是创建一个程序,该程序给出一个文本文件读取其内容,然后返回文件中的单词列表以及该行它们出现的数字以及每行显示单词的次数,格式化为Word Line:Count。

Foo bar bar
Baz
Foo
<EOF>

应返回:

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

到目前为止,我们所涵盖的唯一数据结构是地图,我们使用这些数据编写了以下程序,该程序输出总的wordcount

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个值?或者有更好的方法来实现这样的东西吗?

1 个答案:

答案 0 :(得分:1)

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

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

#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的向量中时,它将为向量分配0 - (n-1)个int的空间。同样在打印时,您必须检查向量中的每个值,看它是否不是0.

您可以通过循环遍历地图中的每个字符串进行打印,然后循环遍历每个键的向量,并仅在索引处的值不为0时进行打印。

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

map<string, map<int, int>> 

具有类似的逻辑。对大多数情况来说哪个更有效。