折半查找
arr[1,2,3,4,5,6,7,8,9,10]
数值:[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ]
下标:[0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
left mid right
若想找到7对应的下标,则先让最左边的下标0作为left,最右边的下标10作为right
right+left=9+0=9, 9/2=4 所以让下标4作为mid
然后arr[4]=5,5<7,所以7在mid和right中间。7在mid(序号4)的右边,
于是让序号5变成新的left ,即left=mid+1;
数值:[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ]
下标:[0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ]
left mid right
然后right+left=9+5=14,14/2=7 所以让下标7作为mid
然后arr[7]=8,8>7,所以7在left和mid中间。7在mid(序号7)的右边,
于是让序号6变成新的right,即right=mid-1;
数值:[1 ,2 ,3 ,4 ,5 ,6 , 7 ,8 ,9 ,10 ]
下标:[0 ,1 ,2 ,3 ,4 ,5 , 6 ,7 ,8 ,9 ]
left right
mid
right+left=5+6=11;11/2=5,所以让下标5作为新的mid
然后arrr[5]=6,6<7,所以7在mid和right中间。7在mid(序号5)右边,
于是让序号6变成新的left,即left=mid+1;
数值:[1 ,2 ,3 ,4 ,5 ,6 , 7 ,8 ,9 ,10 ]
下标:[0 ,1 ,2 ,3 ,4 ,5 , 6 ,7 ,8 ,9 ]
left right
此时left和right都是6,mid也是6,然后判断arr[mid]=arr[6]=7,符合。
如果left和right都特别大,成了long long了。这时候两个加起来再除以2就会有误差,那怎么解决呢?
不能让mid=left/2+right/2 因为3和5的平均值是8/2=4,如果分别/2就是1+2=3,有误差。
【都是因为/会舍掉余数,只保留整数】
所以可以这样mid=left+(right-left)/2
可以理解为两个台阶,left在左边比较低,right在右边比较高,那想让两个台阶变成一样高怎么做,就是先测出来右边比左边高了多少,然后平分成两半,分给left一半,这样就一样高了。
当用arr[]="abc"的时候,可以直接用sizeof(arr)-sizeof(arr[0])来计算这个arr的长度吗?
不可以,因为"abc"实际上是"a b c \0" 那sizeof(arr)-sizeof(arr[0])的结果应该是4;但这里
c的下标应该是2;所以要sizeof(arr)-sizeof(arr[0])-2 才是c的下标。
(减去的一个是\0,一个是“从0开始的下标而不是从1开始”)
或者也可以用strlen
strlen是求出其\0前共有几个字符。因为从0开始的下标而不是从1开始,strlen(arr)-1即可
如果想让程序慢一点可以用Sleep() 括号里面的单位是毫秒,头文件是#include <windows.h>
system("cls") #include <stdlib.h>
char password[20]={0};
当scanf("%s",password)时候不需要加& 因为数组名本身就是地址
两个字符串的比较是不能使用==的
只能使用strcmp(a,b)头文件是#include <string.h>
如果a<b 返回一个值<0
a=b 返回一个值=0
a>b 返回一个值>0
注意,当至少要执行一次的循环,可以用do while。如进入游戏,然后可以再玩一遍游戏,就可以用先玩一次游戏do 然后如果玩家继续玩就可以用while进入循环。
猜数字游戏
生成随机数:rand()返回int;需要用srand来设定生成的随机数,不然每次的rand运行都是一样的随机数顺序。
时间戳:电脑的默认时间与现在时间的差值,单位是秒
time可以返回一个时间戳;srand只用一次就好了,别重复调用
time传地址
goto语句,前面有个n:
然后后面goto n;就直接跳转到n了,再从n这边开始运行。goto不能跨函数跳转。
作用:终止程序中某些深度嵌套中的过程。如一次跳出两层或多层循环。也可以用来当循环。