我有一个包含多个段落的文件A.我需要确定我在哪里匹配来自另一个文件B的单词。我需要告诉每个单词的段落,行号和单词编号,包括那些与文件B中的单词匹配的单词。我到目前为止终于得到了,放弃向量,数组和字符串拆分。我学会了(我认为)stringstream。目前,我在线阅读,然后将其拆分为"。"句子,然后再读回那些句子,分裂在" &#34 ;.我有行数,计数和匹配,但我似乎无法得到段号(我已经意识到p ++实际上是在计算行数,而l ++正在计算单词以及)。有人可以帮帮我吗? 编辑每个段落由" \ n"分隔。每个句子用"分隔。"我仍然需要找出一种方法来忽略所有其他标点符号,以便单词匹配100%,并且不会被逗号,分号或其他标点符号抛出。我猜这将是某个地方的正则表达式。
带文字的文件输入如下:
My dog has fleas in his weak knees. This is a line. The paragraph is ending.'\n' Fleas is a word to be matched. here is another line. The paragraph is ending.'\n'
输出应该类似于:
paragraph1 line 1 word 1 My paragraph1 line 1 word 2 dog paragraph1 line 1 word 3 has paragraph1 line 1 word 4 MATCHED! fleas
while (getline(fin, para)) { //get the paragraphs
pbuffer.clear();
pbuffer.str("."); //split on periods
pbuffer << para;
p++; //increase paragraph number
while (pbuffer >> line) { //feed back into a new buffer
lbuffer.clear();
lbuffer.str(" "); //splitting on spaces
lbuffer << line;
l++; //line counter
while (lbuffer >> word) { //feed back in
cout << "l " << l << " W: " << w << " " << word;
fmatch.open("match.txt");
while (fmatch >> strmatch) { //did I find a match?
if (strmatch.compare(word) == 0) {
cout << " Matched!\n";
}
else {
cout << "\n";
}
}
答案 0 :(得分:1)
既然你说你可以在阅读时写下每个单词,我们就不会打扰一个集合了。我们只需使用istringstream
和istream_iterator
来对抗指数
假设fin
是好的,我将简单地写信给cout
,您可以进行适当的调整以写入您的文件。
1 st 您需要将“fmatch.txt”读入vector<string>
,如此:
const vector<string> strmatch{ istream_iterator<string>(fmatch), istream_iterator<string> }
然后你只想在嵌套循环中使用它:
string paragraph;
string sentence;
for(auto p = 1; getline(fin, paragraph, '\n'); ++p) {
istringstream sentences{ paragraph };
for(auto s = 1; getline(sentences, sentence, '.'); ++s) {
istringstream words{ sentence };
for_each(istream_iterator<string>(words), istream_iterator<string>(), [&, i = 1](const auto& word) mutable { cout << 'w' << i++ << ", p" << p << ", s" << s << (find(cbegin(strmatch), cend(strmatch), word) == cend(strmatch) ? ", word, " : ", namedEntity, ") << word << endl; });
}
}
修改强>
通过解释,我使用for_each
在句子中的每个单词上调用lambda。
让我们分解lambda并解释每个部分的作用:
[&
这通过引用公开lambda声明为lambda的范围内的任何变量供使用:http://en.cppreference.com/w/cpp/language/lambda#Lambda_capture因为我正在使用strmatch
,{{1 lamda中的{}和p
将通过引用s
C ++ 14允许我们在, i = 1]
类型的lambda捕获中声明一个变量,因此auto
是i
,每次调用范围时都会重新初始化其中声明lambda的是retered,这里是嵌套int
- 循环for
这是传递给lambda的参数列表:http://en.cppreference.com/w/cpp/language/lambda此处(const auto& word)
只会传入for_each
s string
因为我正在修改mutable
,这是lambda拥有的,我需要它是非i
所以我声明lambda const
< / LI>
在lambda的主体中,我将使用find
和标准插入运算符来编写值。
<强> EDIT2:强>
如果您仅限于C ++ 11,则无法在lambda捕获中声明变量。你可以在外部提供:
mutable
答案 1 :(得分:1)
我终于搞清楚了,但我没有使用流媒介(对不起!)而且肯定没那么优雅@jonathanMee
我引导了匹配的单词并使用字符串流来读取嵌入它的字符。然后我使用if语句检查段落,并在使用字符串流将数据从一个字符串倾注到另一个字符串时分隔。当我分隔数据时,我增加了,并且匹配完成了。示例:
pholder.clear();
pholder.str("."); //break on the delimiter
pholder << para; //read from the paragraph into pholder
l++;
while (pholder >> line) {// here are all my lines now
lholder.clear();
lholder.str(" "); //breka on the spaces
lholder << line; //read for it