二分查找/猜数字游戏/关机程序
本章将在对一章分支和循环知识进行运用,并学习一些有趣算法和好玩程序
1.二分查找
- 问题引入:当我们需要从1–10里面找一个数字时,好像遍历一遍也很快,但当我们从1–1000000000里面找一个数字时,用便利一遍一遍查找的效率就很低,这时如果我们用二分查找,十几次就找到了。注:有序数组才能使用二分法
- 方法:所谓的二分查找就是每次找最中间的数字和所找数字比较,如1–100里面找数字77,我们先猜50,小了,继续猜75,小了,猜87,大了…最终猜出结果,核心就是不断用中间值和所猜数比较,根据大还是小,进行调整。我们以0–9数字里找7为例,实现算法,图和代码结合理解。
int main()
{
int key = 7; //要查找的数字
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int left = 0; //查找数组最左值
int right = sizeof(arr) / sizeof(arr[0]) - 1; //查找数组最右值,注意这里要在-1哦
int mid = 0;
//比较终止条件,正常比较过程是left和right相互靠近过程,当相等时,比较结束了
while (left<=right)
{
//mid = (left+right)/2; //中间值,有两种写法,第二种写法考虑了left+right超过int类型最大范围
mid = left + (right - left) / 2; //如图2
//比较,中间值小于比较值
if (arr[mid] < key)
{
left = mid + 1; //左left变换
}
//中间值大于比较值
else if (arr[mid] > key)
{
right = mid - 1; //右right变换
}
else //比较值等于中间值
break;
}
//判断,数组内是否有这个数字
if (left <= right)
{
printf("找到了,下标是%d", mid);
}
else
{
printf("找不到\n");
}
return 0;
}
2.猜数字游戏
猜数字游戏框架
int main()
{
int input = 0;
do
{
menu(); /菜单函数,后面要实现功能模块
printf("请输入数字:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game(); /游戏函数,后面要实现的功能模块
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
menu菜单,game游戏功能模块实现
void menu()
{
printf("***********************\n");
printf("******** 1.play *******\n");
printf("******** 0.exit *******\n");
printf("***********************\n");
}
void game()
{
/rand随机生成数字函数,使用rand要调用srand,使用srand又要调用time函数
/调用在main函数中写,这里只是使用rand函数,注:要包含对应函数的头文件
int rand_num = rand() % 100 + 1; /任何数%一个数,得到是0~这个数-1,这里范围是1--100
int key = 0;
while (1)
{
printf("请输入1--100要猜的数字:>");
scanf("%d", &key);
if (key >= 1 && key <= 100) /防止猜数字超出范围
{
if (key > rand_num)
{
printf("猜大了\n");
}
else if (key < rand_num)
{
printf("猜小了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
else
{
printf("猜的数字不在1--100内,请重新猜数字\n");
}
}
}
- 猜数字游戏全部代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
{
printf("***********************\n");
printf("******** 1.play *******\n");
printf("******** 0.exit *******\n");
printf("***********************\n");
}
void game()
{
int rand_num = rand() % 100 + 1;
int key = 0;
while (1)
{
printf("请输入1--100要猜的数字:>");
scanf("%d", &key);
if (key >= 1 && key <= 100)
{
if (key > rand_num)
{
printf("猜大了\n");
}
else if (key < rand_num)
{
printf("猜小了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
else
{
printf("猜的数字不在1--100内,请重新猜数字\n");
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //使用rand函数需要调用
do
{
menu();
printf("请输入数字:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (input);
return 0;
}
3.关机程序
#include <stdio.h>
#include <stdlib.h> /头文件
#include <string.h>
int main()
{
char arr[10] = { 0 };
system("shutdown -s -t 60"); /系统关机程序,真的会关机的
again: /goto跳转标记点,实现了在1分钟内可以一直输入,直到输入我是猪结束关机程序
printf("你的电脑将在1分钟后关机,如果输入:我是猪,就取消关机!");
printf("请输入:>");
scanf("%s", arr);
if (0 == strcmp(arr, "我是猪"))
{
system("shutdown -a"); /取消关机程序
}
else
{
goto again;
}
return 0;
}
4.两端移动,中间汇聚
- 实现功能效果:通过编写代码,演示多个字符从两端移动,向中间汇聚,代码简单,但这个效果很帅,如图,创建两个数组,上一数组内容要慢慢替代下一数组,分别用上数组最左和最右内容覆盖下数组对应内容,然后左++,右++。
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char arr[] = "welcome to home!!!";
char brr[] = "##################";
int left = 0;
int right = strlen(arr) - 1; /减1原因是实际最右边数的下标是对应位置-1
while (left <= right)
{
brr[left] = arr[left];
brr[right] = arr[right];
printf("%s\n", brr);
Sleep(100); /windows下的休眠函数,目的是为了停1s,让我们看到效果,Sleep单位毫秒
system("cls"); /系统清除函数,打印完停留1s后立刻清除屏幕,实现两边滚动式向内走
left++;
right--;
}
printf("%s\n", brr); /最后在打印一下结果,不然被cls清除,最后啥也没了
return 0;
}
4.1.sizeof和strlen的区别
- 在写这篇文章时,我又遇到了,sizeof使用和strlen使用疑惑,像极了曾经对i++和++i的理解混乱,通过查找资料,这里也一起写下来。
1.sizeof()是运算符,strlen()是库函数
2.sizeof()在编译时计算好了,strlen()在运行时计算
3.sizeof()计算对象使用的最大字节数(计算指针是在32位机器上是4,64位上是8), strlen()计算字符串的实际长度,计算是\0之前的字符数。
4.sizeof()的参数类型多样化(数组,指针,对象,函数都可以),strlen()的参数必须是字符型指针(传入数组时自动退化为指针)
在数组/字符串定义时也有区别
char arr[]="abcde";
strlen(arr);sizeof(arr);
char arr[]={'a','b','c','d','e'};
strlen(arr);sizeof(arr);
这两种写法答案一样么,区别在哪里?
- 看完图秒懂,第二种写法不会自动加\0,需要自己手动加上。若未加上,计算strlen直到遇到\0为止(啥时候遇到呢,问系统,咱也不知道)。
使用字符串三种方式
5.总结
好嘞,到这里今天知识讲解就结束了,今天内容是不是很nice,运用分支和循环知识实现各种程序,现在,学习去,冲!!!