当前位置: 首页 > news >正文

内容的逐次呈现以及二分查找(算法)

文章目录

  • 一、多个字符从两端移动,向中间汇聚
  • 二、二分查找
  • 总结

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

相信买过彩票的大家都知道,在彩票开奖的时候,为了保留一定的神秘感,不会将中奖号码直接呈现出来,而是对内容进行一些隐藏,随着倒计时逐渐露出每一位数字。
效果如下:

welcome to ningxia!!!!!!
********************
w******************!
we****************!!
wel**************!!!
welc************!!!!
welco**********!!!!!
......
welcome to ningxia!!!!!!

那我们如果作为后台该程序的编写者,如何编写代码能实现这样的效果呢?

思路解析

这其实就涉及了一个数组的玩法,我们最终打印的数据其实就两份,第一份*********,第二份就是welcome to ningxia!!!。
在我们每次变化的时候,需要把左右两边的字符依次覆盖*,最终达到最后的效果。

理清思路之后我们进行代码的编写

首先我们使用两个数组把这两串内容分别存起来

char arr1[] = "welcome to ningxia!!!!!!";
char arr2[] = "********************";

在这里插入图片描述
接下来就是左右两边对应的位数一一覆盖了,每一次覆盖一对,那我们如何找到相应字符的覆盖位置呢?数组有个特点就是有下标嘛,可以起到定位的作用,我们左边的下标叫做left,右边的下标叫做right,左边的下标从0开始。

int left = 0;

每一次进行覆盖后left向右移一位,right向左移一位

left++;
right--

当我们left和right交错的时候,也就是走到同一个位置的时候,将该位置的字符拿下来覆盖之后,就可以停止了

这里我们可以使用循环来实现这样的不断替换的效果,我这里使用while

while (left <= right)
{arr2[left] = arr1[left];arr2[right] = arr1[right];left++;right--;
}

代码重点

这里有兄弟就要问了,left初始位置好定位呀,0嘛,那right怎么定位呢,难道我每次换个内容还要改定位的位置,有没有什么好的right的定位方法呢?
有的兄弟有的,这样的方法当然是有的,不过需要一点思考计算的。

//如果我给你这样一串代码
char arr[]="abcdef";
[a b c d e f \0]0 1 2 3 4 5 6
//数字是他们的下标

这里如果让你求f的下标5,怎么求呢?
之前写过求数组元素个数的方法,用sizeof

int sz = sizeof(arr) / sizeof(arr[0]);

在这里插入图片描述
这里可以看出该字符串的长度是7,f的下标是5呀,只要-2就可以了,把\0和下标0减去,即sz-2。
在这里插入图片描述
其实呢,这里还有一种我个人认为更简便的方法,还可以使用strlen函数,该函数是用来求字符串长度的,而且自动统计\0之前的字符个数,使用该函数需要包含头文件
#include <string.h>,使用该文件算数组中字符串长度只需要减去下标0就可以了,即-1。
在这里插入图片描述
把前面的总结起来便有了最终的代码:
在这里插入图片描述

有兄弟就说了,你这也不是逐次显示啊,刷一下子全搞出来了,太low了,而且也不是一行代码,搞这么多行不好看,当然不止如此了。

优化内容

这里我们使用一个Sleep函数(睡眠函数),该函数可以使内容慢一点打印,想要具体多慢可以在Sleep括号内加入时间,时间单位是毫秒,这里我们打印间隔要1秒,那就Sleep(1000)

cls

逐次显示代码运行效果

还想要一行展示效果,这里我们的思路是在这一秒内,把上一次打印的东西清理掉,就可以实现了,这里使用system函数,该函数可以处理系统命令,这里也可以打开cmd窗口,打开后不想要窗口内的信息,输入cls(清理屏幕信息),就可以看cls指令的效果了。

最后看到的效果,咦这不对呀,最后怎么没了呢?这里其实是因为最后一次清除了屏幕却停止循环了,所以就什么都没有了,只要在最后加上

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

就可以了。
在这里插入图片描述
相信看到这里大家以及理解了如何将内容逐次呈现了。


二、二分查找

题目:给定一个升序的整型数组,在这个数组中查找到指定的值n,找到了就打印n的下标,找不到就打印“找不到”。
当你看到这个题目,你第一个想到的方法是什么呢?
是不是遍历数组,这是最朴素暴力的方法,即从小打到挨个比较,但是效率极低。
比如我要买一件衣服,你会问我多少钱,我说不超过300,你还是好奇,想知道具体是多少,我就让你猜,你会从1,2,3,4…这样猜嘛?显然这样是很慢的。一般我们都会习惯从中间数字开始猜,这样子的话每猜一次,猜对了就可以砍掉一半的范围,大大提升了效率,这就是二分查找,也叫折半查找

这里先说遍历,如果你想遍历,找到每个元素的下标就可以了

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int n = 7;//在数组arr中找n的值,找到了就打印下标,找不到就打印:找不到//暴力的方法//对数组的元素进行遍历,拿n和每个元素进行比较int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//10for (i = 0; i < sz; i++){if (n == arr[i]){printf("找到了,下标是:%d\n", i);break;}}//

这里如果找不到你要怎么写呢?难道在后面直接跟printf或else?
这都是不对的
这里到//这里有两种情况,第一种是全部比较完了,找不到,第二种是break跳出去来到这,在if }后面跟else,1和7不相等直接打印找不到,显然是不对的,所以要想另一种方法。

这里的i代表的是下标,所以可以这样写

if(i == sz)printf("找不到\n");

那就是下标等于元素个数的时候,那显然全部找完了也找不到嘛,因为下标是从0开始的。展示验证结果:
在这里插入图片描述
在这里插入图片描述

优化(个人认为)

这种方式就不用区分两种情况,多加一个变量found

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int n = 7;//在数组arr中找n的值,找到了就打印下标,找不到就打印:找不到//暴力的方法//对数组的元素进行遍历,拿n和每个元素进行比较int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//10int found = 0;//假设没找到for (i = 0; i < sz; i++){if (n == arr[i]){printf("找到了,下标是:%d\n", i);found = 1;break;}}if (found == 0)printf("找不到\n");return 0;
}

还可以使用布尔类型
在这里插入图片描述
第一种的遍历方法有序无序都可以,而二分法就需要前提条件有序
接下来我们解释怎么把二分查找应用到刚刚的题目里

1 2 3 4 5 6 7 8 9 10
0       4         9
L       M         R

我们想找一个元素,比如说7,怎么找呢?我们先需要求中间元素,那么就要找中间元素的下标,这里我们0下标叫L,9下标叫做R,(0+9)/2=4,这里按整型计算,得到一个平均值,这个值我们称为M,4就是5元素的下标,有人说为什么不能取下标5,对应的元素6呢?其实都不影响,总要去掉一边的,不漏数据就可以了,这里元素5和7比一下,比7要小,所以要找的值在元素5的右边,元素5的左边就去掉了,剩下的元素就是6-10,这时候更新左右下标,右下标不用变,还是R对应的9,左下标要做改变了,怎么变呢?其实就是中间元素的下标+1,就是M+1,变为元素6的下标,毕竟元素5拿出来比较都小了,这新的范围的中间值(5+9)/2=7,7是元素8的下标,也就是新的M,元素8再和7比较,8>7,所以8-10都舍掉了,所以范围变成了6-7,第二次的M就再变化位M-1,而新的L不变,还是元素6,对应的下标(5),R要变,也就是7的下标6,R=M-1,再通过左右下标加起来除2 --(5+6)/2=5,5就是新的M,对应元素6,6比7要小,说明我们要找的值在6的右边,这时候6的右边只有7了,这时候L也要更新成7的下标,也就是L=M+1,这时候L和R都是6了。这时候(6+6)/2=6,对应的元素是7,7与想要的7相等了,便是找到了。

因为这样的更新要持续几轮,所以还要加上循环,这里我依旧用while,因为有可能找不到,能找到的前提是L<=R,要是L>R了,那就交错了,肯定找不到,所以判断的代码是:

while (left <= right)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <stdbool.h>
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int n = 17;//在数组arr中找n的值,找到了就打印下标,找不到就打印:找不到//二分查找方法int left = 0;//左下标int right = sizeof(arr) / sizeof(arr[0]) - 1;//右下标bool found = false;while (left <= right){int mid = (left + right) / 2;if (arr[mid] < n)left = mid + 1;else if (arr[mid] > n)right = mid - 1;else{printf("找到了,下标是:%d\n", mid);found = true;break;}}//if (found == false)printf("找不到\n");return 0;
}

这里无论找不找得到都会来到//,所以还是要判断一下是哪种情况,依旧用到布尔类型


总结

二分查找的步骤就是:

  1. 确定被查找范围的左右下标
  2. 求中间元素的下标
  3. 锁定中间元素和n比较
  • 中间元素arr[M]<n,L=M+1
  • 中间元素arr[M]>n,R=M+1
  • 中间元素arr[M]==n,说明找到了

看完的兄弟肯定能发现,数组玩的就是下标

内容制作不易,写到这里作者都感觉要长脑子了,晕晕的,喜欢的作者内容的靓仔靓女不要忘记一键三连支持一波,你们的支持就是我最大的动力!

相关文章:

  • 【opencv】vs2019中配置opencv
  • 数据结构第4章 栈、队列和数组 (竟成)
  • NTDS.dit 卷影副本提权笔记
  • vue3文本超出三行显示省略号,点击查看更多显示全部文本
  • AI日报 - 2025年05月26日
  • Android开发namespace奇葩bug
  • 基于SpringBoot+RabbitMQ完成应用通信
  • Hadoop集群部署
  • 如何解决大模型返回的JSON数据前后加上```的情况
  • OpenGL Chan视频学习-7 Writing a Shader inOpenGL
  • 使用队列实现栈和使用栈实现队列
  • vue + ant-design + xlsx 实现表格导出进度提示功能
  • 牛客round94E
  • vue3 数值计算 保留小数位
  • 嵌入式学习之系统编程(五)进程(2)
  • day8补充(中断驱动和队列缓冲实现高效数据处理)
  • 文件管理(第八章、九)
  • PDF处理控件Aspose.PDF教程:以编程方式合并PDF文档
  • 一文带你彻底理清C 语言核心知识 与 面试高频考点:从栈溢出到指针 全面解析 附带笔者手写2.4k行代码加注释
  • DP KVM 为何更难实现 EDID 模拟器?
  • 网站在线qq客服代码/怎么能在百度上做推广
  • 仿历史网站模板下载/网络推广网站程序
  • 安徽建工招采平台/英文外链seo兼职
  • 烟台城乡建设住建局网站/关键词搜索趋势
  • 如何建设简易网站/手机系统流畅神器
  • 做易拉宝的素材网站/windows优化大师免费