如何在递归中在C中的另一个字符串中找到字符串位置?

时间:2014-02-21 23:52:47

标签: c string recursion find

我们有一个用两个字符串参数创建递归函数的赋值,原型应该是这样的

int instring( char* word, char* sentence );

如果我们调用函数

instring( "Word", "Another Word" ); 

它应该有以下返回值:

  • 如果找到这个单词,它将返回它在
  • 找到单词的位置
  • 如果找不到这个词,它将返回-1

我可以使用第三个参数来保存位置,但不幸的是我们不允许使用超过2个参数。

所以问题是我该如何运作? 这是我到目前为止所提出的:

int instring( char* word, char* sentence ){
    if( *word == '\0' )
        return 0;
    else if( *word != '\0' && *sentence == '\0' )
        return -1;
    else
        if( *word == *sentence )
            instring( word+1, sentence+1 );
        else
            instring( word, sentence+1 );
}

如果'word'可以找到,我得到0否则我得-1。由于我无法跨函数调用存储任何值,因此无法获得'word'字符串开始的位置。 除了外部变量和只有两个输入字符串之外,还有其他方法可以获得该位置吗?

3 个答案:

答案 0 :(得分:4)

int instring( char* word, char* sentence ){
    int lenw = strlen(word);
    int lens = strlen(sentence);
    if(lenw > lens) return -1;

    if(strncmp(sentence, word, lenw)==0)
        return 0;
    else {
        int ret = instring(word, sentence + 1);
        if(ret < 0)
            return ret;
        return 1 + ret;
    }
}

答案 1 :(得分:2)

我不认为这些是特别优雅的解决方案,但问题也不是很优雅(标准解决方案是迭代的,递归不是最优的)。这是一个纯粹的递归解决方案(没有迭代)效率很低:

#include <stdio.h>

static int const debug = 0;

static int instring(char const *word, char const *sentence)
{
  int rc;
  if (debug)
    printf("-->> [%s] in [%s]\n", word, sentence);
  if (*word == '\0')
    rc = 0;
  else if (*sentence == '\0')
    rc = -1;
  else if (*word != *sentence || (rc = instring(word+1, sentence+1)) != 0)
  {
    if ((rc = instring(word, sentence+1)) >= 0)
      rc++;
  }
  if (debug)
    printf("<<-- [%s] in [%s] = %d\n", word, sentence, rc);
  return rc;
}

int main(void)
{
  char word[] = "Word";
  char str1[] = "Another Word";
  char str2[] = "Wrong parts of the data";
  char str3[] = "A Word Or Two";

  printf("Search for [%s] in [%s] at offset %d\n",
         word, str1, instring(word, str1));
  printf("Search for [%s] in [%s] at offset %d\n",
         word, str2, instring(word, str2));
  printf("Search for [%s] in [%s] at offset %d\n",
         word, str3, instring(word, str3));
  return 0;
}

如果您设置debug = 1;,您就会明白为什么效率低下。它使用变量rc来简化调试跟踪。

这是一种更有效的替代方法,因为当第一个字符匹配时,它使用迭代来限制搜索。不难看出如何删除递归的剩余部分(这是简单的尾递归),留下完全迭代的解决方案,这是解决此问题的常用方法。

#include <stdio.h>

static int instring(char const *word, char const *sentence)
{
  int rc;
  if (*word == '\0')
    return 0;
  if (*sentence == '\0')
    return -1;
  if (*word == *sentence)
  {
    int i;
    for (i = 1; word[i] != '\0' && word[i] == sentence[i]; i++)
      ;
    if (word[i] == '\0')
      return 0;
  }
  if ((rc = instring(word, sentence+1)) >= 0)
    rc++;
  return rc;
}

int main(void)
{
  char word[] = "Word";
  char str1[] = "Another Word";
  char str2[] = "Wrong parts of the data";
  char str3[] = "A Word Or Two";

  printf("Search for [%s] in [%s] at offset %d\n",
         word, str1, instring(word, str1));
  printf("Search for [%s] in [%s] at offset %d\n",
         word, str2, instring(word, str2));
  printf("Search for [%s] in [%s] at offset %d\n",
         word, str3, instring(word, str3));
  return 0;
}

示例输出:

Search for [Word] in [Another Word] at offset 8
Search for [Word] in [Wrong parts of the data] at offset -1
Search for [Word] in [A Word Or Two] at offset 2

可以在两个版本中改进测试代码(通过检查结果是预期的结果,并通过使用测试函数而不是写出如此多的代码三次,并且可能通过使用循环来扫描测试数据

答案 2 :(得分:0)

int len1 = strlen(word);
int len2 = strlen(sentence);
int n,k=0;

for(int i =0;i<len2;i++){
n =i;
  while(sentence[n] == word[k] && n<len2){
      if(k==len1 && ( n==len2 || sentence[n+1] ==' ')
        return i;//if word found return the position in the original string//
        n++;
        k++;
 }
k =0;
while(sentence[i] != ' ' && i<len2) //go to next word//
i++;
}
return -1;