【C语言习题演练】分支与循环——字符移动问题

封面

导言

大家好,很高兴又和大家见面啦!!!在上一篇的内容里我们简单介绍了数组的相关内容,详细介绍了二分法的相关内容,并通过二分法解答了在有序数组中查找数字n的问题。今天我们带来的习题如下:

  1. 编写代码,演示多个字符从两端移动,向中间汇聚。

今天通过这个习题,我们又将介绍哪些新的知识点呢?下面让我们一起来看一下吧;

多个字符从两端移动,向中间汇聚

这一题看完感觉有点不太理解题目是什么意思,别着急,咱们先通过图片来理解一下这一题的具体要求:
字符从两端向中间汇聚示意图
通过图片内容我们可以知道,这一题是需要我们在屏幕中打印字符,并且这个字符是从两端往中间依次打印,就比如我要打印"hello world!!!"这串字符,那我就需要按照两端往中间打印的方式:

打印次数打印内容
第一次打印h############!
第二次打印he##########!!
第三次打印hel########!!!
第四次打印hell######d!!!
第五次打印hello####ld!!!
第六次打印hello ##rld!!!
第七次打印hello world!!!

(注:在这个编辑器中因为无法用空格来将字符隔开,所以我这里借助了#来起到一个隔开字符的作用,并不是说题目要求我们一定是用#来实现字符往中间汇聚)

具体应该如何实现呢?下面我们就来分析一下;

题目解析

从刚刚的例子中我们可以得到的信息是:

  1. 我们需要一串字符;
  2. 我们需要将字符打印出来;
  3. 字符需要从两端向中间打印;

与之对应的,我们就需要实现两个功能:

  1. 功能一——打印一串字符;
  2. 功能二——将字符从两端开始向中间打印;

下面我们就可以通过代码来一一实现这两个功能了

代码实现

功能一——打印一串字符

对于功能一的打印我们并不陌生,通过printf就能实现,那这一串字符我们又应该如何实现呢?
这里我们简单介绍一下什么是一串字符,这一串字符又该怎么表示?

字符串

在C语言中由双引号“”引起的单个或多个字符就是字符串如:" "“abc”“hello world”这些都是字符串。
在字符串中有些结论这里我先给大家介绍一下,目前了解即可,后续会详细介绍:

由双引号引起的字符串都存在一个看不见的字符——\0
\0是字符串的结束标志;
“”——这也是一个字符串,它叫做空字符串,因为在双引号里面没有除了\0以外的其它元素;
我们可以通过字符类型的数组来存储字符串;
字符串可以通过%s打印出来;

在已知这些信息后,我们就可以实现功能一将字符串打印出来了,如图所示:
打印字符串

那下面如何实现功能二将字符从两端打印呢?下面我们就来探讨一下;

功能二——字符从两端向中间打印

方式一——直接求解

在上一篇介绍二分法的时候我们有介绍过,我们可以通过数组下标来访问数组元素,数组最后一位元素下标比数组的大小小1。这时有朋友可能就会说了,既然如此,那这样不就好解决了吗?我们直接按照数组下标将字符依次打印出来(打印字符时使用%c),如图所示:
打印字符串2
看到打印结果,会不会比较疑惑?诶,为啥最后一个元素没有打印啊?别急,下面我们来看一下这个数组究竟是个什么情况:
数组内容
从图中我们可以看到,在这个大小为20的ch数组中确实有20个元素,但是最后一个元素的值为\0,并不是我们想要的!。而我们想要的!它的下标是13,这是为什么呢?
会导致这种情况的出现是因为我们已知的元素个数在这个数组中小于数组的大小;
这里我们可以得出结论,在数组中最后一个元素并不一定是我们已知元素的最后一位,那如何求我们已知元素的最后一位的下标呢?
这里我们要介绍一个新的库函数——strlen

库函数strlen

strlen——计算字符串长度的库函数,使用这个库函数时需要引用头文件string.h
下面我们来计算一下这个字符串的长度,如图所示:
计算字符串长度
从图中我们可以看到计算的结果为14,这个结果刚好就是我们这串字符的字符个数,在前面的监视窗口我们看到了我们需要打印的最后一个元素!它的下标是13,刚好比这个结果少1,因此我们可以得到结论:

  1. strlen计算的字符串长度就是看得到的字符的个数;
  2. strlen在计算字符串长度时,遇到\0就停止;
  3. 在数组中,字符串的长度比字符串除\0外的最后一个字符的下标多1;

接下来我们就可以来测试一下通过下标和七次打印来实现功能二:
暴力求解
从测试结果中我们可以看到,通过这种方式能够实现功能二,但是这个代码有点一言难尽啊。
下面我们来思考一下有没有更好的方式来解决这个问题呢?
有朋友马上就想到了,我们可以通过循环语句来解决呀!那有没有朋友知道为什么能够通过循环语句来解决这个问题呢?
因为我们在前面这种方式实现功能二的时候其实是在重复的进行这打印这个指令,只不过打印的内容有变化而已,循环语句的功能就是重复去做一件事情,所以这个问题我们是可以通过循环语句来解决的。

方式二——循环求解

在方式一的实现过程中,我们通过在输出时加入了空格让打印时的展现形式是从两端像中间汇聚,随着每一次打印,中间的空格数量都会减少,随着最后一次打印,原先所有的空格都被数组中的元素给取代了

按照方法一的思路,我们可不可以通过设计循环语句来实现用数组里的元素来取代空格呢?答案是可以的,只需要再借助一个数组就可以完成,下面我们借助图示来理解取代的过程:
字符取代过程
通过图解,我们可以看到,我们只需要将辅助数组内容的元素进行一一替换就行,下面我们来尝试一下这种方式能不能行:
字符替换
从测试结果中我们可以看到,通过这种元素替换的方式可以实现将字符一个个打印出来,下面我们就要思考如果想要从两端往中间打印的话,我们又应该如何编写代码?

元素替换

实现从两端打印的第一步肯定是元素的替换,在刚刚的测试中我们进行的是首元素的替换,那从两端打印的话,我们肯定是要进行首元素和末端元素的替换:

	ch2[0] = ch[0];
	ch2[j - 1] = ch[j - 1];

如果放在循环中进行依次替换的话,根据数组下标的结论:

数组下标从0开始逐渐递增;

那我们要依次进行替换的话左边的元素是依次增加的,右边的元素是依次减少的,如下表所示:

循环次数左端元素下标(i)右端元素下标(j-1)
1ij-1
2i+1(j-1)-1
3i+1+1(j-1)-1-1

依次类推,直到左端元素下标与右端元素下标相邻或相等。对应的代码如下:

	for (i = 0; i <= j; i++)
	{
		ch2[i] = ch[i];
		ch2[j - 1] = ch[j - 1];
		j --;
	}

现在我们的元素替换就完成了,我们只需要在每次替换完之后打印一次就可以了,如图所示:
字符从两端取代
可以看到现在我们就很好的完成了这一题的要求。

知识拓展

接下来,我要给大家分享一些知识点让这个代码的打印方式变的高级起来。

睡眠函数——Sleep()——通过此函数可以让计算机进入睡眠状态,函数参数单位为毫秒;
系统函数——system()——通过此函数可以使用计算机的各个指令;
清屏指令——“cls”——通过该指令可以实现清屏的操作;

Sleep函数

Sleep函数是Windows系统的自带函数,所以在使用Sleep函数时需要引用头文件Windows.h
在使用Sleep函数时,S必须是大写。

system函数及清屏指令

使用system函数需要引用头文件stdlib.h
cls是cmd中用来清除cmd屏幕显示字符的命令,全称是clear screen(清空屏幕);
所谓的cmd也就是VS中的控制台,我更习惯的称呼它为运行窗口;
我们在使用system函数来执行cls指令时,需要加上双引号system(“cls”)

运行结果展示

在了解完上述内容,现在我们来让我们的代码运行变的高级起来:
字符从两端向中间汇聚
这里我是通过截图然后生成的视频转gif图片,所以我设置的时长是12秒,你们自己在运行时可以设置为1秒,这样感受会更加的直观。原码如下:

#include <stdio.h>
#include <string.h>//使用strlen需要引用的头文件
#include <Windows.h>//使用Sleep需要引用的头文件
#include <stdlib.h>//使用system需要引用的头文件
int main()
{
	char ch[20] = "hello world!!!";
	char ch2[20] = "              ";
	int i = 0;//定义下标
	int j = strlen(ch);//定义字符串变量
	for (i = 0; i <= j; i++)
	{
		ch2[i] = ch[i];
		ch2[j - 1] = ch[j - 1];
		j--;
		printf("%s\n", ch2);
		Sleep(1000);//打印完之后停留1秒钟的时间
		system("cls");
	}
	printf("%s\n", ch2);
	return 0;
}

现在我们就完成了这一题的全部内容了,希望大家能从这一题中学习到元素替换思想Sleep函数的使用system函数的使用以及cls命令的使用

结语

今天的内容到这里就全部结束了,通过今天的题目,我们简单介绍了字符串strlen函数Sleep函数system函数以及cls命令,希望大家通过今天的内容能够熟悉了解相关的知识点,接下来我们还是会继续通过习题来巩固分支与循环的相关内容,大家记得关注哦!
最后感谢各位的翻阅,咱下一篇再见!!!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值