• 用递归实现字符串逆序(不使用库函数)



    前言

    嗨,亲爱的读者们!我是艾老虎尤,今天,我们将探索一个题目,这个题目对新手非常友好,。在这个题目中,我们将遇到各种编程元素,输入输出,条件语句,指针,循环,函数和递归,当然如果你是老手的话,也可以和我一起复习一下这些最基础的知识,话不多说,我们直接开始。


    一、题目要求

    编写一个函数 reverse_string(char * string)(递归实现)

    实现: 将参数字符串中的字符反向排列,不是逆序打印。

    要求: 不能使用C函数库中的字符串操作函数

    比如:

    char arr[] = "abcdef";
    
    • 1

    逆序之后数组的内容变成:fedcba

    二、解题步骤

    1.大概框架

    首先我们利用最基本的信息先把整个框架写出来,比如他要一个字符串,要一个函数,我们就可以先把这些和主函数写出来。

    代码如下(示例):

    #include
    //返回类型  函数名     函数体
    void reverse_string(char* arr)
    {
    
    }
    
    int main()
    {
    	char arr[] = "abcdef";//字符串
    	reverse_string(arr);//定义的函数
    	return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    数组名就是数组首元素的地址,是地址的话函数就要使用指针接收

    2.如何反向排列?

    首先我们设想一下,假设一个字符里面存储的是abcdef,咱们可以先调转af的位置,然后再调转be的位置,然后再调转cd的位置,用代码怎么实现呢?实际上很简单,a就是字符串第一个元素,f就是字符串里面最后一个元素,所以我们先要求出字符串的长度。


    3.模拟实现strlen

    我们都是到有一个库函数叫做strlen,它的逻辑就是求从第一个字符开始向后进行查找,直到遇到字符串的结束标志\0,就返回\0之前出现过字符的总和,就是求出字符串的长度,但是题目规定不能使用库函数,所以我们就模拟实现库函数。

    代码如下(示例):

    #include
    int my_strlen(char* arr)
    {
    	int count = 0;//计数器
    	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
    	{
    		count++;//计数器自增1
    		arr++;//找到下一个需要对比的元素
    	}
    	printf("字符串的长度是:%d\n", count);
    	return count;
    }
    
    //返回类型  函数名     函数体
    void reverse_string(char* arr)
    {
    	int len = my_strlen(arr);//自定义函数求字符串长度
    }
    
    int main()
    {
    	char arr[] = "abcdef";//字符串
    	reverse_string(arr);//定义的函数
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    4.实现反向排列

    当我们知道了字符串的长度之后,我们就定义两个变量,
    一个叫left,对应的是我们第一个元素的位置
    第二个叫right,对应的是我们最后一个元素的位置
    当我们交换完一对元素后,让left向后移动一位,找到下一个元素,在让right向前移动一位,找到上一个元素,接下来我为大家画图展示。

    在这里插入图片描述

    上图我们发现,交换的过程是一个循环,而当right>left的时候,就证明元素全部交换完了,不需要再进行下去了,由此我们可以写出以下代码。

    代码如下(示例):

    #include
    int my_strlen(char* arr)
    {
    	int count = 0;//计数器
    	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
    	{
    		count++;//计数器自增1
    		arr++;//找到下一个需要对比的元素
    	}
    	printf("字符串的长度是:%d\n", count);
    	return count;
    }
    
    //返回类型  函数名     函数体
    void reverse_string(char *arr)
    {
    	int len = my_strlen(arr);//自定义函数求字符串长度
    	int left = 0;
    	int right = len - 1;
    	while (right > left)
    	{
    		//交换两个元素
    		char tmp = *(arr+left);
    		*(arr + left) = *(arr+right);
    		*(arr + right) = tmp;
    		left++;
    		right--;
    	}
    }
    
    int main()
    {
    	char arr[] = "abcdef";//字符串
    	reverse_string(arr);//定义的函数
    	printf("%s", arr);
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    写到这里的时候,就已经可以实现反向排列了。

    运行效果:
    在这里插入图片描述

    可是题目要求我们使用递归解决,于是我要改进一下代码,让代码符合题意。


    5.递归实现反向排列

    递归的两个必要条件
    1.存在限制条件,当满足这个限制条件的时候,递归便不再继续。
    2.每次递归调用之后越来越接近这个限制条件

    之前我们的思路是把第一个元素放到倒数第一的位置上,把第二个元素放到倒数第二的位置上,以此内推,实际上我们也可以把问题看成,先交换第一个元素和最后一个元素,再递归第二个元素,以此内推,我还是画图为大家展示。

    在这里插入图片描述

    void reverse_string(char* arr)
    {
    	int len = my_strlen(arr);//自定义函数求字符串长度
    	char tmp = *arr;
    	*arr = *(arr + len - 1);
    	*(arr + len - 1) = tmp;
    
    	reverse_string(arr + 1);//递归从下一个元素开始
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这里我们会发现第一个问题,就是当第一次交换完后,再进入reverse_string函数如果从下一个元素开始的话,递归就会混乱,我画图为大家展示。

    在这里插入图片描述

    想解决这个问题也不难,我们只需要改变语句的执行顺序,先把最后元素赋值成 \0,等递归结束再把a的值赋值给\0

    void reverse_string(char* arr)
    {
    	int len = my_strlen(arr);//自定义函数求字符串长度
    	char tmp = *arr;
    	*arr = *(arr + len - 1);
    	*(arr + len - 1) = '\0';
    
    	reverse_string(arr + 1);
    
    	*(arr + len - 1) = tmp;
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    最后我们给递归添加一个限制条件,不然的话他会一直递归下去,限制条件就是当递归里面的元素大于等于2时,才需要继续递归。

    完整代码:

    #include
    int my_strlen(char* arr)
    {
    	int count = 0;//计数器
    	while (*arr != '\0')//如果这个元素不等于结束标志,进入循环
    	{
    		count++;//计数器自增1
    		arr++;//找到下一个需要对比的元素
    	}
    	printf("字符串的长度是:%d\n", count);
    	return count;
    }
    
    //返回类型  函数名     函数体
    void reverse_string(char* arr)
    {
    	int len = my_strlen(arr);//自定义函数求字符串长度
    	char tmp = *arr;
    	*arr = *(arr + len - 1);
    	*(arr + len - 1) = '\0';
    	if(my_strlen(arr+1)>=2)
    		reverse_string(arr + 1);
    
    	*(arr + len - 1) = tmp;
    
    
    }
    
    int main()
    {
    	char arr[] = "abcdef";//字符串
    	reverse_string(arr);//定义的函数
    	printf("%s", arr);
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    效果展示:
    在这里插入图片描述


    总结

    在本篇博客中,我们讨论了如何使用递归的方式来实现字符串的逆序。通过不使用库函数,我们需要仅仅使用递归来实现这一功能。

    首先,我们讨论了递归的基本概念和原理,指出了使用递归的条件:问题可以被分解为较小的子问题,并且每个子问题可以通过调用相同的函数来解决。然后,我们通过编写一个递归函数来实现字符串的逆序。

    在实现递归函数时,,我们使用递归的方式,将字符串的第一个字符与最后一个字符进行交换,从而实现字符串的逆序。我们将交换后的字符串作为一个新的问题传递给递归函数,直到递归到边界条件,逆序的字符串最后返回。

    最后,我们给出了逆序字符串的示例代码,并通过测试验证了递归函数的正确性。

    通过本篇博客的学习,我们深入理解了递归的原理和应用,掌握了使用递归函数来实现字符串逆序的方法。递归函数的实现过程相对简单,但需要注意边界条件的处理和递归调用的方式。

  • 相关阅读:
    JVM的默认内存是怎么分配的?
    算法训练day41|动态规划 part03(LeetCode343. 整数拆分、96.不同的二叉搜索树)
    JavaScript/uni-app对接海康ISC openapi
    小程序简单版音乐播放器
    ArangoDB 社区分布式集群 部署
    2022-11-11 C++并发编程( 四十一 )
    JDBC的基本使用(mysql与java)
    【kafka】docker + 单点kafka部署 + nodejs生产者和消费者
    学习残差神经网络(ResNet)
    本周监管状态更新,以下平台一定要远离!
  • 原文地址:https://blog.csdn.net/qq_69611919/article/details/132782316