定位字符串中匹配的单词
locating matched words in a string
我有一个文件a,有多个段落。我需要确定我在哪里匹配了另一个文件b中的单词。我需要告诉每个单词的段落、行号和单词号,包括那些与文件b中的单词匹配的单词。到目前为止,我已经放弃了向量、数组和字符串分割。我学过(我想)stringstream。目前,我读一行,然后在"。"上把它分成句子,然后再把这些句子读回去,在"上分开。我有行号计数,单词计数和匹配,但我似乎就是无法得到段落号(我已经意识到p++实际上是在计算行数,而l++也在计算单词数)。有人能帮帮我吗?edit每个段落用"n"分隔,每个句子用"。"分隔。我仍然需要找到一种方法来忽略所有其他标点符号,以便单词100%匹配,并且不会被逗号、分号或其他标点符号所遗漏。我猜这将是一个正则表达式在那里的某个地方。
从文件中输入的文本看起来像:
我的狗虚弱的膝盖上长了跳蚤。这是一条直线。这段结束了。'n'跳蚤是一个可以匹配的词。这是另一行。这段结束了。'n'之前输出应该看起来像这样:
<>之前第1段第1行第1词我的第1段第1行第2词狗第1段第1行第3字有第1段第1行第4字匹配!跳蚤之前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";
}
}
既然您说可以在读取时写入每个单词,那么我们就不使用集合了。我们就用istringstream
和istream_iterator
来对指标。
假设fin
是好的,我将简单地写入cout
,您可以进行适当的调整以写入您的文件。
1st你需要在你的"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; });
}
}
<<p> 生活例子/kbd> 编辑:作为解释,我使用for_each
对句子中的每个单词调用lambda。
让我们分解lambda并解释每个部分的作用:
-
[&
通过引用,将lambda声明的作用域中的任何变量暴露给lambda以供使用:http://en.cppreference.com/w/cpp/language/lambda#Lambda_capture因为我在lambda中使用strmatch
,p
和s
,这些将通过引用 捕获 -
, i = 1]
c++ 14允许我们在auto
类型的lambda捕获中声明一个变量所以i
是int
每次进入lambda声明的作用域时都会重新初始化,这里是嵌套的for
-loop 的每个条目 -
(const auto& word)
这是传递给lambda的参数列表:http://en.cppreference.com/w/cpp/language/lambda这里for_each
将只是传递在string
s -
mutable
因为我正在修改i
,它是由lambda拥有的,我需要它是非const
,所以我声明lambdamutable
在lambda的主体中,我将使用find
和标准插入操作符来编写值。
EDIT2:
如果限于c++ 11,则不能在lambda捕获中声明变量。你可以在外部提供:
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 };
auto i = 1;
for_each(istream_iterator<string>(words), istream_iterator<string>(), [&](const auto& word){ cout << 'w' << i++ << ", p" << p << ", s" << s << (find(cbegin(strmatch), cend(strmatch), word) == cend(strmatch) ? ", word, " : ", namedEntity, ") << word << endl; });
}
}
我终于弄明白了,但是我没有使用流交互器(对不起!)当然也没有那么优雅@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
- 从字符串变量中逐字符读取单词
- 使用std::mt19937从字符串中返回一个随机单词
- C++-字符串是否包含一个带有简单循环的单词
- 在C++中查找(奇怪的)字符串中的单词
- 当字符串是某个单词时给出输出?
- 替换字符串中的单词,但忽略引号中的单词
- 替换字符串位置 X 中的单词C++
- 视觉C++使用 map 来比较字符串中的每个单词
- 给定一个单词数组和一个字符串,如何计算给定字符串中的所有单词
- 输出返回编号。等于输入字符串的单词的字符串数
- 在字符串的每个单词的末尾插入字符串
- 分析字符串中的双精度和单词
- 如何使用运算符>>在自定义字符串中输入多个单词?
- 反转字符串中单词的位置,而不更改 O(1) 空格限制中特殊字符的顺序
- 使用正则表达式c++从单词和分隔符之间的字符串中提取所有子字符串
- 从文件 (C++) 输入两个单词字符串
- 在一行中输入具有其他输入类型的多个单词字符串
- 打印以 "a" 开头的单词(字符串中)
- 如何让我的代码以不会切断单词(字符串)的方式运行?
- 句子变成单词c++字符串