在字符串中搜索模式

时间:2016-09-26 08:05:12

标签: c++ recursion

我真的很难获得递归,但我尝试使用递归来匹配字符串中的模式。

假设我有一个字符串 geeks for geeks ,我有一个模式 eks 来匹配。我可以使用很多方法,如正则表达式找到字符串类的方法,但我真的想通过递归来做这件事。

为了达到这个目的,我尝试了这段代码:

void recursion(int i,string str)
{
    if(!str.compare("eks"))
        cout<<"pattern at :"<<i<<'\n';

    if(i<str.length() && str.length()-1!=0)
        recursion(i,str.substr(i,str.length()-1));
}

int main()
{
    string str("geeks for geeks");

    for(int i=0;i<str.length();i++)
        recursion(i,str.substr(i,str.length()));
}

输出:

enter image description here

所需的输出:

pattern at 2
pattern at 12

我在这里做错了什么,以及通过递归来做这件事的好方法是什么?

我理解cpp中的很多主题,但是通过递归,我知道它们是如何工作的,甚至每当我尝试用递归编写代码时,它都无法工作。可以有任何地方可以帮助我进行递归?

2 个答案:

答案 0 :(得分:5)

您永远不会得到pattern at 2,因为compare并非如此。问问自己,将会是什么

std::string("eks for geeks").compare("eks")

返回?好吧,根据documentation,你会得到一些积极的东西,因为"eks for geeks""eks"长。所以你的第一步是解决这个问题:

void recursion(int i, std::string str){
  if(!str.substr(0,3).compare("eks")) {
    std::cout << "pattern at: " << i << '\n';
  }

接下来,我们必须递归。但是还有一些东西。 i应该是&#34;光标&#34;的当前位置。因此,你应该推进它:

  i = i + 1;

如果我们在每次迭代中减少字符串的长度,我们就不能测试i < str.length,否则我们不会检查字符串的后半部分:

  if(str.length() - 1 > 0) {
    recursion(i, str.substr(1));
  }
}

在我们实际编译此代码之前,请理解它:

  • 我们有一个正确长度的子字符串,用于与"eks"
  • 进行比较
  • 除了当前位置
  • ,我们从不使用i
  • 我们在递交之前推进了这个位置
  • 我们&#34;推进&#34;删除第一个字符的字符串
  • 我们最终会在某个时候出现一个空字符串

似乎合理:

#include <iostream>
#include <string>

void recursion(int i, std::string str){
  if(!str.substr(0,3).compare("eks")) {
    std::cout << "pattern at: " << i << '\n';
  }

  i = i + 1;

  if(str.length() - 1 > 0) {
    recursion(i, str.substr(1));
  }
}

int main () {
    recursion(0, "geeks for geeks");
    return 0;
}

输出:

pattern at: 2
pattern at: 12

但是,这不是最佳选择。有几种可能的优化。但这是一个练习。

锻炼

    由于它的算法,
  1. compare需要使用substr。编写自己的比较函数,不需要substr
  2. 正在进行大量的复制。你可以摆脱它吗?
  3. for循环错误。为什么?

答案 1 :(得分:1)

递归函数不能进入循环。你有一些错误。试试这段代码。

void recursion(string str, string subStr, int i){
    if(str.find(subStr) != string::npos ) {
        int pos = str.find(subStr);
        str = str.substr(pos + subStr.length(), str.length()-1);
        cout << "pattern at " << (pos + i) << endl;
        recursion(str, subStr, pos+subStr.length() );
    }
}

int main(int argc, char** argv) {
    string str("geeks for geeks");
    string subStr("eks");
    recursion(str, subStr, 0);
    return 0;
}