void function(无打印) - 使用递归反转字符串

时间:2015-01-03 11:11:11

标签: c

我想在C语言中编写一个反转单词的递归函数。我知道如何打印它,但实际上扭转了我不知道如何的原始单词。 所以,我想编写一个函数来反转一个单词,使用指针,使用string.h,但必须是无效的,不打印,并更改原始单词。功能原型:     void reverse(char * string); 我能写的是递归的停止条款(我不确定它们是否正确);

if(!string) return; // if the string is empty
if(*(string+1)=='\0' return (*string); // if there is only on char in the string
if(*(string+2))=='\0' // if there are only 2 letters In the strings-swap
temp=(*string);
(*string)= * (string+1);
(*string+1)= temp; // I don't know what to do after..
很棒的是,伙计们可以向我解释该怎么做。 谢谢。

3 个答案:

答案 0 :(得分:0)

尾递归的实现:

#include <stdio.h>
#include <string.h>

/* function prototypes */
void reverse(char *string);
void reverseWorker(char *string, int start, int end);

int main(int argc, const char *argv[]) {
  char string[] = "Hello, world.";
  printf("string (original) = %s\n", string);
  /*
  reverse(string);

  Or, to reverse each word in the string...
  */

  char *ptr = strtok(string, " ");
  while(ptr != NULL) {
    reverse(ptr);
    ptr = strtok(NULL, " ");
    if(ptr != NULL)
      *(ptr-1)=' ';
  }

  /* the rest is the same */

  printf("string (reversed) = %s\n", string);
  return 0;
}

void reverse(char *string) {
  reverseWorker(string, 0, strlen(string)-1);
}

void reverseWorker(char *string, int start, int end) {
  /* terminal condition */
  if(start>=end)
    return;
  /* swap */
  char temp = string[start];
  string[start]=string[end];
  string[end]=temp;
  /* recursive step */
  reverseWorker(string,start+1,end-1);
}

答案 1 :(得分:0)

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void reversefill(char*const from,char*const to){
    if(from>=to){
        //Nothing to do. Odd lengths get to from==to.
        //Even lengths 'swap over'.
        //Pointer comparison guaranteed legit - in the same array.
        return;
    }
    //Textbook swap.
    //Could use the classic xor swap trick.
    //However that will just confuse in this example.
    const char temp=*from;
    *from=*to;
    *to=temp;

    //Carry on moving our 'work' points closer together from both ends.
    reversefill(from+1,to-1);
}

void reverse(char* str){
    const size_t sz=strlen(str);
    if(sz==0){
        return;//Can't use str-1 - UB.
        //Could head for the door if sz==1 but this is a training example on recursion.
        //So we'll just show it works if from==to.
    }
    reversefill(str,str+sz-1);
}

int main() {
    char*const str="Hello World!";
    char*const rev=malloc(strlen(str)*sizeof(*str));//sizeof not required but good habit

    strcpy(rev,str);

    reverse(rev);

    printf("%s\n",rev);

    free(rev);//Don't listen to smart-arses who say that's unnecessary. 
    //Unless you really need to use the trick...
    //However examples should be the cleanest possible code.

    return EXIT_SUCCESS;
}

我认为要求是就地逆转。

这样做的唯一方法(我认为OP意识到)是从最终开始工作并交换“对称”&#39;位置。这是交换第一个与最后一个,第二个与第二个交换,等等。

那没关系,但我们需要意识到我们什么时候见过#39;在中间。 奇怪的长度案例显而易见 - 两个工作点相遇。 对于偶数情况,我们需要发现工作情况并越过&#39;。

reversefill(,)的确如何运作。

我认为这段代码是C字符串优缺点的绝佳标本。 主要功能非常有效。

但实际上必须扫描两次字符串,因为C本身没有提供O(1)方法来获取字符串的长度!

答案 2 :(得分:0)

您可以编写类似

的功能
void reverse( char s[] )
{
    reverse_impl( s, strlen( s ) );
}

void reverse_impl( char s[], size_t n )
{
    if ( !( n < 2 ) )
    {
        char c = s[0];
        s[0] = s[n-1];
        s[n-1] = c;
        reverse_impl( s + 1, n - 2 );
    }
}

但它是一个错误的解决方案,因为它不是函数void reverse( char s[] );,它是一个递归函数。函数void reverse_impl( char s[], size_t n );是递归的。但根据你的任务,函数void reverse( char s[] );必须是递归的。

所以正确的解决方案如下。

#include <stdio.h>

void reverse( char s[] )
{
    if ( *s  )
    {
        char *p = s;
        char c;

        do
        {
                    c = *p;
                    *p = *( p + 1 );
                    *( p + 1 ) = c; 
        } while ( *p++ );

        reverse( s );

        c = *p;
        *p = *( p - 1 );
        *( p - 1 ) = c;
    }
}


int main( void ) 
{
    char s[] = "abcde";

    puts( s );
    reverse( s );
    puts( s );

    return 0;
}

输出

abcde
edcba

这个递归函数既不使用标准函数:)