广告位联系
返回顶部
分享到

C语言通过二分查找实现猜数字游戏

C语言 来源:互联网 作者:佚名 发布时间:2023-02-05 21:39:20 人浏览
摘要

二分查找 题目: 在一个有序数组中查找具体的某个数字n。 首先我们先定义一个110的数组 ,如果7为我们要查找的数字,编写代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

二分查找

题目: 在一个有序数组中查找具体的某个数字n。

首先我们先定义一个1···10的数组 ,如果7为我们要查找的数字,编写代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#include <stdio.h>

int main()

{

    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

    //  下标          0 1 2 3 4 5 6 7 8 9

    int k = 7;//k是要查找的数字

    int i = 0;

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

     //sz为数组元素个数

    int flag = 0;//

    for (i = 0; i < sz; i++)

    {

        if (k == arr[i])

        {

            flag = 1;

            printf("找到了,下标是:%d\n", i);

            break;

        }

    }

    if (flag == 0)

        printf("找不到\n");

 

    return 0;

}

但是这个代码的效率比较低,需要循环多次,所以我们需要用一个效率较高的方法:二分查找又叫 (折半查找)

二分查找的思想

给你一个有序的序列,取中间元素和目标元素进行对比,取其中的一半,丢弃另一半,快速缩小目标元素所在的位置。主要思想还是:快速缩小目标元素所在的区间。

二分查找的条件

1.序列必须是有序的,升序或者降序都可以

2. 序列必须是顺序存储元素的,顺序存储元素主要是可以快速的获取中间元素(可以通过下标来找到元素)

二分查找的实现过程

分析:假设我们要找的数字为7,在查找过程中要用下标进行查找,此时我们定义左下标为left,右下标为right,中间元素下标为mid,(left+right)/2=mid。当第一次查找没有找到时,从中间下标向左或向右缩短查找范围继续查找,直到找到为止。

以数字7为例:第一次查找(left+right)/2=(0+9)/2=4,下标为4找到的数字为5,此时并没有找到;第二次查找,因为数字5小于数字7,所以mid+1=left,right不变,向右查找,此时(left+right)/2=(5+9)/2=7,下标为7,找到的数字为8,并没有找到;第三次查找,因为数字8大于数字7,所以mid-1=right,左下标不变,向左查找,此时(left+right)/2=(5+6)/2=5,下标为5,找到的数字为6,第四次查找,因为6小于7,所以向右查找,(left+right)/2=(6+6)/2=6,下标为6,找到的数字为7。

代码举例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

#include <stdio.h>

int main()

{

    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

    // 下标       0 1 2 3 4 5 6 7 8 9

    int k = 7;//k是要查找的数字

    int i = 0;

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

    //折半查找(二分查找),前提是数组有序

    int left = 0;

    int right = sz - 1;

 

    int flag = 0;

    while (left<=right)

    {

        int mid = (left + right) / 2;

        if (arr[mid] < k)

        {

            left = mid + 1;

        }

        else if (arr[mid] > k)

        {

            right = mid - 1;

        }

        else

        {

            printf("找到了,下标是:%d\n", mid);

            flag = 1;

            break;

        }

    }

    if (flag == 0)

        printf("找不到\n");

 

    return 0;

}

如果left是一个很大的数,right也是一个很大的数,left+right超出整形能表达的最大值,数据溢出,此时(left+right)/2所求的就不是最大值了这时要怎么办呢?

我们让多出的部分除以二在平分,如图所示

代码修改

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

#include <stdio.h>

int main()

{

    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };

    //            0 1 2 3 4 5 6 7 8 9

    int k = 7;//k是要查找的数字

    int i = 0;

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

    //折半查找(二分查找),前提是数组有序

    int left = 0;

    int right = sz - 1;

 

    int flag = 0;

    while (left<=right)

    {

        int mid = left + (right - left) / 2;

 

        if (arr[mid] < k)

        {

            left = mid + 1;

        }

        else if (arr[mid] > k)

        {

            right = mid - 1;

        }

        else

        {

            printf("找到了,下标是:%d\n", mid);

            flag = 1;

            break;

        }

    }

    if (flag == 0)

        printf("找不到\n");

 

    return 0;

}

猜数字游戏

游戏说明

1.电脑生成一个1~100的的随机数

2.猜数字

猜大了 就告诉你:猜大了

猜小了 就告诉你:猜小了

猜对了 就告诉你:恭喜你,猜对了

猜数字游戏思想

首先要打印一个菜单,选择开始游戏还是退出游戏

其次,游戏应该可以玩完一局之后玩一局,为循环进行,利用循环语句构建框架

代码实现

打印菜单

1

2

3

4

5

6

7

void menu()

{

    printf("*****************************\n");

    printf("*********   1. play  ********\n");

    printf("*********   0. exit  ********\n");

    printf("*****************************\n");

}

打印结果

打印主函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

int main()

{

    int input = 0;

    do

    {

        menu();

        printf("请选择:>");

        scanf("%d", &input);

        switch (input)

        {

        case 1:

            printf("猜数字\n");

            break;

        case 0:

            printf("退出游戏\n");

            break;

        default:

            printf("选择错误\n");

            break;

        }

    } while (input);

    return 0;

}

此时游戏过于简单,选择1要开始游戏,所以我们定义一个游戏函数game()

打印游戏函数

游戏第一步:生成随机数

rand()函数为生成随机数函数,头文件为<stdlib.h>

rand会返回一个0~327637之间的数

使用rand()要搭配srand() 一起使用,srand()是设置随机数生成器,一般用时间戳作为时间的种子,所以使用time函数来获取时间,然后将time函数转换为(unsigned)类型在传给srand函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

void game()

{

    //1. 生成随机数

    int ret = rand() % 100 + 1;//0~99+1-->1~100

    //2. 猜数字

    int guess = 0;

    while (1)

    {

        printf("请猜数字:>");

        scanf("%d", &guess);

        if (guess < ret)

        {

            printf("猜小了\n");

        }

        else if (guess > ret)

        {

            printf("猜大了\n");

        }

        else

        {

            printf("恭喜你,猜对了\n");

            break;

        }

    }

}

整体代码演示

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

#include <stdlib.h>

#include <stdio.h>

#include <time.h>

 

void menu()

{

    printf("*****************************\n");

    printf("*********   1. play  *******\n");

    printf("*********   0. exit  ********\n");

    printf("*****************************\n");

}

//

//rand函数会返回一个0~32767之间的随机数

//

//时间戳

 

void game()

{

    //1. 生成随机数

    int ret = rand() % 100 + 1;//0~99+1-->1~100

    //2. 猜数字

    int guess = 0;

    while (1)

    {

        printf("请猜数字:>");

        scanf("%d", &guess);

        if (guess < ret)

        {

            printf("猜小了\n");

        }

        else if (guess > ret)

        {

            printf("猜大了\n");

        }

        else

        {

            printf("恭喜你,猜对了\n");

            break;

        }

    }

}

 

int main()

{

    int input = 0;

    //设置了随机数的生成器

    srand((unsigned int)time(NULL));

    //给srand传一个时间戳,是生成的数字足够随机

    do

    {

        menu();

        printf("请选择:>");

        scanf("%d", &input);

        switch (input)

        {

        case 1:

            game();

            break;

        case 0:

            printf("退出游戏\n");

            break;

        default:

            printf("选择错误\n");

            break;

        }

    } while (input);

    return 0;

}

游戏效果演示


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/2201_75366661/article/details/128838309
相关文章
  • 一篇文章彻底搞懂C++常见容器

    一篇文章彻底搞懂C++常见容器
    1.概述 C++容器属于STL(标准模板库)中的一部分(六大组件之一),从字面意思理解,生活中的容器用来存放(容纳)水或者食物,东西,
  • C语言通过二分查找实现猜数字游戏

    C语言通过二分查找实现猜数字游戏
    二分查找 题目: 在一个有序数组中查找具体的某个数字n。 首先我们先定义一个110的数组 ,如果7为我们要查找的数字,编写代码如下 1 2
  • Matlab实现绘制高阶版本韦恩图(upset图)

    Matlab实现绘制高阶版本韦恩图(upset图)
    韦恩图随着阶数升高会越来越复杂,当阶数达到7或者以上时几乎没办法绘制: 但是使用upset图却可以比较轻易的绘制: 两种类型图的对应关
  • 通俗易懂的C语言快速排序和归并排序的时间复杂
    今天面试的时候,被问到归并排序的时间复杂度,这个大家都知道是O(nlogn),但是面试官又继续问,怎么推导出来的。这我就有点懵了,
  • C语言学习基础知识分享

    C语言学习基础知识分享
    写在前面 我们正式开始接触到C语言,这是我在学习过C语言后重新写的博客,我把之前的稍微优化了一下,希望能用更加朴素的语言和大家分享
  • C语言基础知识分享续篇

    C语言基础知识分享续篇
    写在前面 好了,现在我们开始C语言的第二个部分.今天我们需要看下面几个知识点,都是非常简单的,我们主要认识一下. 数组 我们知道一个一
  • C语言实现求解素数的N种方法

    C语言实现求解素数的N种方法
    哈喽各位友友们,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!我仅已此文,手把手带领大家探讨利用试除法、筛
  • C语言利用goto语句设计实现一个关机程序

    C语言利用goto语句设计实现一个关机程序
    goto语句其实在平常中我们 除了学习分支语句和循环语句时,介绍循环语句时,才会知道有goto语句这个用法,那读者可能会问:我们还有学
  • VS及Unity安装和使用Nuget包

    VS及Unity安装和使用Nuget包
    一、百科 Nuget是一个包(package)管理平台,确切的说是.net平台的包管理工具,它提供了一系列客户端用于生成,上传和使用包(package),
  • C/C++ Qt实现文章小说人物关系分析

    C/C++ Qt实现文章小说人物关系分析
    一、所需工具软件 1. Visual Stuido 2. C++ 二、使用步骤 1.引入库 代码如下(示例): 1 2 3 4 5 6 7 8 9 10 11 #include QtGuiApplication1.h #includeqDebug #incl
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计