[英]Tokenization of a text file with frequency and line occurrence. Using C++
我再次寻求帮助。 我有一段时间没有编码了!
现在,我有一个文本文件,里面充满了乱码。 我已经对如何计算每个单词的出现次数有了一个基本的想法。
真正让我感到困扰的是我将如何确定单词所在的行。直觉告诉我要在每行的末尾查找换行符。 但是我必须在第一次浏览文本文件时执行此操作,对吗? 因为如果我这样做后遗症,那就没有用了。
我已经通过以下代码得到这些单词:
vector<string> words;
string currentWord;
while(!inputFile.eof())
{
inputFile >> currentWord;
words.push_back(currentWord);
}
这是针对没有设置结构的文本文件。 使用以上代码为我提供了一个很好的单词(大)矢量,但并没有给我它们出现的界线。
我是否必须掌握整条线,然后将其加工成文字才能使之成为可能?
使用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
其放入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));
}
您将不得不放弃对string
s的读取,因为operator >>(istream&, string&)
会丢弃空格,并且空格的内容( == '\\n'
或!= '\\n'
,即问题...)是什么会给您行号。
这是OOP可以节省一天的时间。 您需要编写一个类作为读取文件的“前端”。 它的工作是缓冲文件中的数据,并一次将一个单词返回给调用者。
在内部,该类需要一次从一个文件块(例如4096字节)中读取数据。 然后,一个string GetWord()
(是的,按值返回是好的)方法将:
\\n
时增加对象的lineNumber
成员。 string
对象中。 string
就是整个单词(可能为空),应将其返回。 然后,您可以在代码中与cin >>
行相同的位置调用此方法,而代码的其余部分不需要知道块缓冲的详细信息。
另一种方法是一次读取一行,但是所有适用于您的读取功能都需要您创建一个固定大小的缓冲区以事先读取,如果行长于该缓冲区,则必须以某种方式处理它。 它可能会比我描述的课程更加复杂。
简短而甜美。
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";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.