Paxwell
Paxwell

Reputation: 758

Learning recursion: How can I locate a substring index within a string without using find?

I have a recursive function to find the starting index of a substring within a string. I am learning to use recursion, so the find function is not allowed. I believe I have met most of the conditions. This function is supposed to find the correct index in the string. If it is blank it returns -1.

Here is the real problem. If I enter a string "nothing" and search for "jax" it doesn't return -1. I don't understand why. Any help please? Here is the code:

The user would enter string s and t passed into below:

int index_of(string s, string t)
{
    int start = 0;
    int len2 = t.length();
    int index = 0;

    if (s == "")
    {
        return -1;
    }
    else if (s.substr(1).length() <= t.length())
    {
        return -1;
    }
    else if ( s.substr(start, len2) == t)
    {
        return index;
    }
    else
    {
        index ++;
        return index + index_of(s.substr(1), t);
    }
    return -1;
}

Upvotes: 0

Views: 1809

Answers (2)

Michael Kristofik
Michael Kristofik

Reputation: 35188

The best way to learn how to debug problems like this is to work them out on paper. Your example is small enough that it shouldn't take too long. It's pretty clear that you're going to fall into your else case in the first few steps because the strings don't match. So we have:

index_of("nothing", "jax"):
    index++;  // index is now 1
    return 1 + index_of("othing", "jax");
index_of("othing", "jax"):
    index++;  // index is now 1
    return 1 + index_of("thing", "jax");
etc.

Does that help?

Upvotes: 1

jogojapan
jogojapan

Reputation: 69967

There are several problems -- some minor ones, and some quite important ones.

  1. You have two variables, start and index, to indicate "the current position", but one would be enough.

  2. index can only be 0 or 1. Therefore, the way it is currently written, you could easily get rid of index and start altogether.

  3. Important: When, during the final recursion, the end of the string is reached, you return -1 to the previous recursive call. Then, because of the way the recursive calls are done, you add 1 and return that to the previous call, and so forth. The value finally returned is the -1 plus the length of the string. That is why you get strange results.

  4. This comparison

    if (s.substr(1).length() <= t.length())
    

    does not make much sense.

Taking all of this into account, here is an improved version:

#include <iostream>
#include <string>

int index_of(
  const std::string &s,
  const std::string &t,
  const size_t index)
{
  int len2  = t.length();

  if ((s.length() - index) < t.length())
    return -1;
  else if (s.substr(index,len2) == t)
    return index;
  else
    return index_of(s,t,index + 1);
  return -1;
}

/** Overloading, so you can call index_of with just
    two arguments */
int index_of(const std::string &s, const std::string &t)
{
  return index_of(s,t,0);
}

/** Some test cases. */
int main()
{
  std::cout << index_of("hello","ello") << std::endl;
  std::cout << index_of("nothing","jax") << std::endl;
  std::cout << index_of("hello","llo") << std::endl;
  std::cout << index_of("hello","lo") << std::endl;
  std::cout << index_of("hello","o") << std::endl;
  std::cout << index_of("hello","hel") << std::endl;
}

Upvotes: 1

Related Questions