这个字符串反向递归是如何工作的?

时间:2012-09-30 17:00:41

标签: c recursion

我通常很好地理解递归,但因为我是strcpy等C函数和指针的新手,我无法弄清楚这种递归如何反转字符串:

char *reverse(char *string)
{
    if (strlen(string) <= 1)
        return string;

    else
    {
        char temp = *string;

        strcpy(string, reverse(string+1));

        *(string+strlen(string)) = temp;

        return string;
    }
}

strcpy部分对我来说似乎有点复杂,而且这条线的目的是什么:
*(string+strlen(string)) = temp;

我意识到在翻转字符串之后你需要将字符串添加到字符串结尾处,但我不确定我是否理解这段代码背后的逻辑。

3 个答案:

答案 0 :(得分:2)

这段代码效率极低,但它的作用是:

  1. 保存原始第一个字符
  2. 以递归方式反转字符串的其余部分(string+1是指向字符串中第二个字符的指针。)
  3. 将(反向)字符串的其余部分复制到左侧一个字符。
  4. 将原始的第一个字符放在最后(*(string+strlen(string)) = temp;)。
  5. 如果更容易理解,*(string+strlen(string)) = temp;相当于string[strlen(string)] = temp;

    我根本不建议使用这个代码,因为它效率非常低 - 它会在每次迭代中复制整个字符串(并测量其长度两次),更不用说浪费堆栈空间了。

    更好的实施方式是:

    void reverse(char *s) {
      char *e = s+strlen(s)-1;
      while (e > s) {
        char tmp = *s;
        *s=*e;
        *e=tmp;
        s++; e--:
      }
    }
    

答案 1 :(得分:0)

*(string+strlen(string)) = temp是所谓的指针算法 - 该代码等同于string[strlen(string)] = temp。因此,这会将 temp 字符放在字符串的末尾。请注意,字符串仍然保持为零终止,因为reverse()返回与其参数长度相同的字符串。

reverse(string+1)再次是指针算术,这次与reverse(&string[1])相同 - 即 reverse()将从第二个字符开始镜像字符串 ,但是 strcpy()会将它放在字符串的开头,覆盖存储在 temp 中的第一个字符并放在字符串的末尾。

然而,整体代码看起来不必要地复杂且效率低下,所以在抽取有关如何从中做事的任何课程之前,我会三思而行。

答案 2 :(得分:0)

这就是代码的工作原理。输入字符串分为两部分, 第一个角色,其余的。第一个字符存储在temp中, 其余的通过递归调用来反转。递归调用的结果放在结果的开头,temp中的字符放在结尾。

string is [1234567890]

temp is 1, string+1 is [234567890]

reverse(string+1) is [098765432], temp is 1

strcopy行是在reverse(string+1)开头复制string结果的部分,而*(string+strlen(string)) = temp是复制temp的部分string的结尾。