具有频率和行出现的文本文件的标记化。使用C ++

时间:2010-09-13 22:00:30

标签: c++ file-io tokenize

我再一次请求帮助。我有时候没有编码任何东西!

现在我有一个充满随机乱码的文本文件。我已经对如何计算每个单词的出现次数有一个基本的想法。

真正让我感到困惑的是我将如何确定这个词的位置.Gut本能告诉我在每一行的末尾寻找换行符。但是,我必须在第一次浏览文本文件时这样做吗?因为如果我这样做,它就会没用。

我已经通过以下代码获得了这些文字:

vector<string> words;
string currentWord;

while(!inputFile.eof())
{
inputFile >> currentWord;
words.push_back(currentWord); 
}

这是针对没有设置结构的文本文件。使用上面的代码给了我一个很好的小(大)字的向量,但它没有给我他们出现的行。

我是否必须获得整行,然后将其处理为单词以使其成为可能?

3 个答案:

答案 0 :(得分:3)

使用std::map<std::string, int>计算单词出现次数 - int是其存在的次数。

如果您需要按行输入,请使用std::getline(std::istream&, std::string&),如下所示:

std::vector<std::string> lines;
std::ifstream file(...) //Fill in accordingly.
std::string currentLine;
while(std::getline(file, currentLine))
    lines.push_back(currentLine);

您可以先将一条线拆分为std::istringstream,然后再使用operator>>。 (或者,您可以使用std::find和其他算法原始图形来填充某种分割器

编辑:这与@ dash-tom-bang的回答是一样的,但在错误处理方面被修改为正确:

vector<string> words;
int currentLine = 1; // or 0, however you wish to count...

string line;
while (getline(inputFile, line))
{
   istringstream inputString(line);
   string word;
   while (inputString >> word)
      words.push_back(pair(word, currentLine));
}

答案 1 :(得分:0)

您将不得不放弃阅读string,因为operator >>(istream&, string&) 会丢弃空白区域和空白区域的内容(== '\n'!= '\n',这就是问题......)会给你一些行号。

这是OOP可以节省一天的地方。您需要编写一个类来充当从文件中读取的“前端”。它的工作是缓冲文件中的数据,并一次一个地返回给调用者。

在内部,类需要一次从文件中读取数据(例如,4096字节)。然后string GetWord()(是的,这里按值返回是好的)方法将:

  • 首先,读取任何空格字符,每次点击lineNumber时都要注意增加对象的\n成员。
  • 然后阅读非空格字符,将它们放入您将要返回的string对象中。
  • 如果要读取的内容不足,请阅读下一个块并继续。
  • 如果您点击文件的末尾,则您拥有的string是整个单词(可能为空),应该返回。
  • 如果函数返回一个空字符串,则告诉调用者已到达文件末尾。 (文件通常以空白字符结尾,因此读取空白字符并不意味着稍后会有一个单词。)

然后,您可以在代码中与cin >>行相同的位置调用此方法,其余代码不需要知道块缓冲的详细信息。

另一种方法是一次读取一行,但所有适用于您的读取函数都需要您创建一个固定大小的缓冲区以便事先读取,如果该行长于该缓冲区,你必须以某种方式处理它。它可能比我描述的类更复杂。

答案 2 :(得分:0)

简短又甜蜜。

vector< map< string, size_t > > line_word_counts;

string line, word;
while ( getline( cin, line ) ) {
    line_word_counts.push_back();
    map< string, size_t > &word_counts = line_word_counts.back();

    istringstream line_is( line );
    while ( is >> word ) ++ word_counts[ word ];
}

cout << "'Hello' appears on line 5 " << line_word_counts[5-1]["Hello"]
     << " times\n";