在字符串中查找匹配的单词

时间:2016-11-15 12:30:35

标签: c++ stringstream

我有一个包含多个段落的文件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";
                }

            }

2 个答案:

答案 0 :(得分:1)

既然你说你可以在阅读时写下每个单词,我们就不会打扰一个集合了。我们只需使用istringstreamistream_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; });
    }
}

Live Example

修改

通过解释,我使用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捕获中声明一个变量,因此autoi,每次调用范围时都会重新初始化其中声明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