二分查找/猜数字游戏/关机程序--通关教学

二分查找/猜数字游戏/关机程序

本章将在对一章分支和循环知识进行运用,并学习一些有趣算法和好玩程序

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.猜数字游戏

  • 游戏描述:电脑生成一个随机数,我们作为玩家在键盘上输入来猜数字,猜大了,电脑告诉我们大了…直到猜对为止结束。
  • 要实现较为复杂些项目都是先将基本框架写出来,然后根据框架一一实现功能,rand,srand,time函数:rand函数srand函数time函数
猜数字游戏框架
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.关机程序

  • 关机程序作为一个非常有意思代码,实现起来却十分简单,这里使用goto跳转,但其实用循环也是可以实现的。
  • strcmp,system函数:strcmp函数system函数
#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,运用分支和循环知识实现各种程序,现在,学习去,冲!!!
请添加图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值