用递归实现字符串逆序(不使用库函数)
文章目录
- 前言
- 一、题目要求
- 二、解题步骤
- 1.大概框架
- 2.如何反向排列?
- 3.模拟实现strlen
- 4.实现反向排列
- 5.递归实现反向排列
- 总结
前言
嗨,亲爱的读者们!我是艾老虎尤,今天,我们将探索一个题目,这个题目对新手非常友好,。在这个题目中,我们将遇到各种编程元素,输入输出,条件语句,指针,循环,函数和递归,当然如果你是老手的话,也可以和我一起复习一下这些最基础的知识,话不多说,我们直接开始。
一、题目要求
编写一个函数 reverse_string(char * string)(递归实现)
实现: 将参数字符串中的字符反向排列,不是逆序打印。
要求: 不能使用C函数库中的字符串操作函数。
比如:
char arr[] = "abcdef";
逆序之后数组的内容变成:fedcba
二、解题步骤
1.大概框架
首先我们利用最基本的信息先把整个框架写出来,比如他要一个字符串,要一个函数,我们就可以先把这些和主函数写出来。
代码如下(示例):
#include<stdio.h>
//返回类型 函数名 函数体
void reverse_string(char* arr)
{}int main()
{char arr[] = "abcdef";//字符串reverse_string(arr);//定义的函数return 0;
}
数组名就是数组首元素的地址,是地址的话函数就要使用指针接收
2.如何反向排列?
首先我们设想一下,假设一个字符里面存储的是abcdef,咱们可以先调转
a
和f
的位置,然后再调转b
和e
的位置,然后再调转c
和d
的位置,用代码怎么实现呢?实际上很简单,a
就是字符串第一个元素,f
就是字符串里面最后一个元素,所以我们先要求出字符串的长度。
3.模拟实现strlen
我们都是到有一个库函数叫做strlen,它的逻辑就是求从第一个字符开始向后进行查找,直到遇到字符串的结束标志
\0
,就返回\0
之前出现过字符的总和,就是求出字符串的长度,但是题目规定不能使用库函数,所以我们就模拟实现库函数。
代码如下(示例):
#include<stdio.h>
int my_strlen(char* arr)
{int count = 0;//计数器while (*arr != '\0')//如果这个元素不等于结束标志,进入循环{count++;//计数器自增1arr++;//找到下一个需要对比的元素}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;
}
4.实现反向排列
当我们知道了字符串的长度之后,我们就定义两个变量,
一个叫left,对应的是我们第一个元素的位置
第二个叫right,对应的是我们最后一个元素的位置
当我们交换完一对元素后,让left向后移动一位,找到下一个元素,在让right向前移动一位,找到上一个元素,接下来我为大家画图展示。
上图我们发现,交换的过程是一个循环,而当
right>left
的时候,就证明元素全部交换完了,不需要再进行下去了,由此我们可以写出以下代码。
代码如下(示例):
#include<stdio.h>
int my_strlen(char* arr)
{int count = 0;//计数器while (*arr != '\0')//如果这个元素不等于结束标志,进入循环{count++;//计数器自增1arr++;//找到下一个需要对比的元素}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;
}
写到这里的时候,就已经可以实现反向排列了。
运行效果:
可是题目要求我们使用递归解决,于是我要改进一下代码,让代码符合题意。
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);//递归从下一个元素开始}
这里我们会发现第一个问题,就是当第一次交换完后,再进入
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;}
最后我们给递归添加一个限制条件,不然的话他会一直递归下去,限制条件就是当递归里面的元素大于等于2时,才需要继续递归。
完整代码:
#include<stdio.h>
int my_strlen(char* arr)
{int count = 0;//计数器while (*arr != '\0')//如果这个元素不等于结束标志,进入循环{count++;//计数器自增1arr++;//找到下一个需要对比的元素}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.模拟实现strlen4.实现反向排列5.递归实现反向排列 总结 前言 嗨,亲爱的读者们!我是艾老虎尤,今天,我们将探索一个题目,这个题目对新手非…...

初学python(一)
一、python的背景和前景 二、 python的一些小事项 1、在Java、C中,2 / 3 0,也就是整数 / 整数 整数,会把小数部分舍掉。而在python中2 / 3 0.66666.... 不会舍掉小数部分。 在编程语言中,浮点数遵循IEEE754标准,不…...

Excel VSTO开发8 -相关控件
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 8 相关控件 在VSTO开发中,Ribbon(或称为Ribbon UI)是指Office应用程序中的那个位于顶部的带有选…...

华为数据管理——《华为数据之道》
数据分析与开发 元数据是描述数据的数据,用于打破业务和IT之间的语言障碍,帮助业务更好地理解数据。 元数据是数据中台的重要的基础设施,元数据治理贯彻数据产生、加工、消费的全过程,沉淀了数据资产,搭建了技术和业务…...

Flink CDC 菜鸟教程 -环境篇
本教程将介绍如何使用 Flink CDC 来实现这个需求, 在 Flink SQL CLI 中进行,只涉及 SQL,无需一行 Java/Scala 代码,也无需安装 IDE。 系统的整体架构如下图所示: 环境篇 1、 准备一台Linux 2、准备教程所需要的组件 下载 flink-1.13.2 并将其解压至目录 flink-1.13.2 …...
【线上问题】linux部署docker应用docker-compose启动报端口占用问题(感觉上没有被占用)
目录 一、问题说明二、排查过程 一、问题说明 1.linux服务器使用的不是root用户权限 2.docker应用服务没有关闭的情况下,做了些重装docker,重启docker等操作 3.docker-compose up -d然后docker logs查看日志报端口被占用 4.netstat -ntpl | grep 端口 也…...

解决虚拟机克隆后IP和命名冲突问题
目录 解决IP冲突问题 解决命名冲突 解决IP冲突问题 克隆后的虚拟机和硬件地址和ip和我们原虚拟机的相同,我们需要重新生成硬件地址和定义ip,步骤如下: (1)进入 /etc/sysconfig/network-scripts/ifcfg-ens33 配置文件…...

分享一个python基于数据可视化的智慧社区服务平台源码
💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、Node.js、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! …...
[密码学入门]凯撒密码
单表代换 单表:英文26字母的顺序 代换:替换为别的字母并保证解密的唯一性 假如我们让加密方式为所有字母顺序移动3位 import stringstring.ascii_lowercase abcdefghijklmnopqrstuvwxyz b3 加密算法y(xb)mod26 解密算法为x(y-b)mod26 密钥空间26 …...

博客之QQ登录功能(一)
流程图 上图spring social 封装了1-8步需要的工作 1、新建包和书写配置文件 public class QQProperties {//App唯一标 识private String appId "100550231";private String appSecret "69b6ab57b22f3c2fe6a6149274e3295e";//QQ供应商private String…...

Redis多机数据库实现
Redis多机数据库实现 为《Redis设计与实现》笔记 复制 客户端可以使用SLAVEOF命令将指定服务器设置为该服务器的主服务器 127.0.0.1:12345> SLAVEOF 127.0.0.1 6379127.0.0.1:6379将被设置为127.0.0.1:123456的主服务器 旧版复制功能的实现 Redis的复制功能分为同步&a…...

Leangoo领歌 -敏捷任务管理软件,任务管理更轻松更透明
任务管理,简单易懂,就是对任务进行管理。那怎么可以更好进行任务管理呢?怎么样样可以让任务进度可视化,一目了然呢?有效的管理可以让我们事半功倍。 接下来我们看一下如何借助任务管理软件高效的做任务管理。 首先…...

go的iris框架进行本地资源映射到服务端
我这里使用的是HandleDirapi,有其他的请补充 package mainimport ("github.com/kataras/iris/v12" )type Hello struct{Status int json:"status"Message string json:"message" }func main(){app : iris.New()//第一个api:相当于首页app.Get(&q…...
代码随想录day46|139. 单词拆分
139. 单词拆分 class Solution:def wordBreak(self, s: str, wordDict: List[str]) -> bool:dp [False]*(len(s)1)dp[0]Truefor i in range(len(s)1):for j in wordDict:if i>len(j) and (s[i-len(j):i] in wordDict) and dp[i-len(j)]:dp[i] Truereturn dp[len(s)]多…...

MATLAB实现函数拟合
目录 一.理论知识 1.拟合与插值的区别 2.几何意义 3.误差分析 二.操作实现 1.数据准备 2.使用cftool——拟合工具箱 三.函数拟合典例 四.代码扩展 一.理论知识 1.拟合与插值的区别 通俗的说,插值的本质是根据现有离散点的信息创建出更多的离散点…...

vue优化首屏加载时间优化-cdn引入第三方包
前言 为什么要进行首屏加载优化,因为随着我们静态资源和第三方包和代码增加,压缩之后包会越来越大 随着网络的影响,在我们第一输入url请求资源时候,网络阻塞,加载时间长,用户体验不好 仔细观察后就会发现…...
lv4 嵌入式开发-3 标准IO的读写
目录 1 标准I/O – 读写流 2 标准I/O – 按字符输入 3 标准I/O – 按字符输出 4 标准I/O – 思考和练习 5 标准I/O – 按行输入 6 标准I/O – 按行输出 7 标准I/O – 思考和练习 1 标准I/O – 读写流 流支持不同的读写方式: 读写一个字符:fgetc()/fputc()一…...
iOS UIDevice设备信息
识别设备和操作系统 //获得共享设备实例 open class var current: UIDevice { get }//识别设备的名称 open var name: String { get } // e.g. "My iPhone"//设备类型 open var model: String { get } // e.g. "iPhone", "iPod touch"//本地化设…...
SLAM ORB-SLAM2(2)编译安装
SLAM ORB-SLAM2(2)编译安装 1. 软件包依赖安装2. 依赖安装2.1. Eigen2.2. Pangolin2.3. OpenCV3. ORB-SLAM23.1. 源码下载3.2. 文件修改3.3. 扩大交换空间3.4. 编译1. 软件包依赖安装 以一个纯净的ubuntu20.04桌面版为例 1.首先设置软件源为清华源 2.安装必要依赖 sudo ap…...
第11节-PhotoShop基础课程-索套工具
文章目录 前言1.索套工具 选中后按Ctrl 可以移动2.加,减,交叉 shift alt 2.多边形索套工具 手动首尾相连 或者双击空地1.单击绘制直线选区2.双击结束绘制3.加,减,交叉4. delete可以删除节点 3.磁性索套工具1.沿着边缘自动吸附2.可…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...