经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C语言通过二分查找实现猜数字游戏
来源:jb51  时间:2023/2/6 9:00:54  对本文有异议

二分查找

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

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

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
  5. // 下标 0 1 2 3 4 5 6 7 8 9
  6. int k = 7;//k是要查找的数字
  7. int i = 0;
  8. int sz = sizeof(arr) / sizeof(arr[0]);
  9. //sz为数组元素个数
  10. int flag = 0;//
  11. for (i = 0; i < sz; i++)
  12. {
  13. if (k == arr[i])
  14. {
  15. flag = 1;
  16. printf("找到了,下标是:%d\n", i);
  17. break;
  18. }
  19. }
  20. if (flag == 0)
  21. printf("找不到\n");
  22.  
  23. ??????? return 0;
  24. }

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

二分查找的思想

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

二分查找的条件

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. #include <stdio.h>
  2. int main()
  3. {
  4. int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
  5. // 下标 0 1 2 3 4 5 6 7 8 9
  6. int k = 7;//k是要查找的数字
  7. int i = 0;
  8. int sz = sizeof(arr) / sizeof(arr[0]);
  9. //折半查找(二分查找),前提是数组有序
  10. int left = 0;
  11. int right = sz - 1;
  12.  
  13. int flag = 0;
  14. while (left<=right)
  15. {
  16. int mid = (left + right) / 2;
  17. if (arr[mid] < k)
  18. {
  19. left = mid + 1;
  20. }
  21. else if (arr[mid] > k)
  22. {
  23. right = mid - 1;
  24. }
  25. else
  26. {
  27. printf("找到了,下标是:%d\n", mid);
  28. flag = 1;
  29. break;
  30. }
  31. }
  32. if (flag == 0)
  33. printf("找不到\n");
  34.  
  35. return 0;
  36. }

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

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

代码修改

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
  5. // 0 1 2 3 4 5 6 7 8 9
  6. int k = 7;//k是要查找的数字
  7. int i = 0;
  8. int sz = sizeof(arr) / sizeof(arr[0]);
  9. //折半查找(二分查找),前提是数组有序
  10. int left = 0;
  11. int right = sz - 1;
  12.  
  13. int flag = 0;
  14. while (left<=right)
  15. {
  16. int mid = left + (right - left) / 2;
  17.  
  18. if (arr[mid] < k)
  19. {
  20. left = mid + 1;
  21. }
  22. else if (arr[mid] > k)
  23. {
  24. right = mid - 1;
  25. }
  26. else
  27. {
  28. printf("找到了,下标是:%d\n", mid);
  29. flag = 1;
  30. break;
  31. }
  32. }
  33. if (flag == 0)
  34. printf("找不到\n");
  35.  
  36. return 0;
  37. }

猜数字游戏

游戏说明

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

2.猜数字

猜大了 就告诉你:猜大了

猜小了 就告诉你:猜小了

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

猜数字游戏思想

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

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

代码实现

打印菜单

  1. void menu()
  2. {
  3. printf("*****************************\n");
  4. printf("********* 1. play ********\n");
  5. printf("********* 0. exit ********\n");
  6. printf("*****************************\n");
  7. }

打印结果

打印主函数

  1. int main()
  2. {
  3. int input = 0;
  4. do
  5. {
  6. menu();
  7. printf("请选择:>");
  8. scanf("%d", &input);
  9. switch (input)
  10. {
  11. case 1:
  12. printf("猜数字\n");
  13. break;
  14. case 0:
  15. printf("退出游戏\n");
  16. break;
  17. default:
  18. printf("选择错误\n");
  19. break;
  20. }
  21. } while (input);
  22. return 0;
  23. }

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

打印游戏函数

游戏第一步:生成随机数

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

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

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

  1. void game()
  2. {
  3. //1. 生成随机数
  4. int ret = rand() % 100 + 1;//0~99+1-->1~100
  5. //2. 猜数字
  6. int guess = 0;
  7. while (1)
  8. {
  9. printf("请猜数字:>");
  10. scanf("%d", &guess);
  11. if (guess < ret)
  12. {
  13. printf("猜小了\n");
  14. }
  15. else if (guess > ret)
  16. {
  17. printf("猜大了\n");
  18. }
  19. else
  20. {
  21. printf("恭喜你,猜对了\n");
  22. break;
  23. }
  24. }
  25. }

整体代码演示

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <time.h>
  4.  
  5. void menu()
  6. {
  7. printf("*****************************\n");
  8. printf("********* 1. play *******\n");
  9. printf("********* 0. exit ********\n");
  10. printf("*****************************\n");
  11. }
  12. //
  13. //rand函数会返回一个0~32767之间的随机数
  14. //
  15. //时间戳
  16.  
  17. void game()
  18. {
  19. //1. 生成随机数
  20. int ret = rand() % 100 + 1;//0~99+1-->1~100
  21. //2. 猜数字
  22. int guess = 0;
  23. while (1)
  24. {
  25. printf("请猜数字:>");
  26. scanf("%d", &guess);
  27. if (guess < ret)
  28. {
  29. printf("猜小了\n");
  30. }
  31. else if (guess > ret)
  32. {
  33. printf("猜大了\n");
  34. }
  35. else
  36. {
  37. printf("恭喜你,猜对了\n");
  38. break;
  39. }
  40. }
  41. }
  42.  
  43. int main()
  44. {
  45. int input = 0;
  46. //设置了随机数的生成器
  47. srand((unsigned int)time(NULL));
  48. //给srand传一个时间戳,是生成的数字足够随机
  49. do
  50. {
  51. menu();
  52. printf("请选择:>");
  53. scanf("%d", &input);
  54. switch (input)
  55. {
  56. case 1:
  57. game();
  58. break;
  59. case 0:
  60. printf("退出游戏\n");
  61. break;
  62. default:
  63. printf("选择错误\n");
  64. break;
  65. }
  66. } while (input);
  67. return 0;
  68. }

游戏效果演示

以上就是C语言通过二分查找实现猜数字游戏的详细内容,更多关于C语言猜数字的资料请关注w3xue其它相关文章!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号