我想在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..
很棒的是,伙计们可以向我解释该怎么做。
谢谢。
答案 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
这个递归函数既不使用标准函数:)