如何避免C语言猜数字程序重复猜测已排除的数字?
解决猜数字程序重复猜测已排除数字的问题
嘿,刚学C语言就能写出这样的程序已经很棒了!你遇到的重复猜数字问题,根源在于用随机数的方式没法精准跟踪已经排除的范围——随机数可不会记得之前猜过什么,所以很容易撞已经被排除的数。其实换个思路,用二分查找法来猜数字就完美解决这个问题了,不仅不会重复,还能最快猜到目标数,比随机高效太多!
先说说你现有代码的两个关键问题:
- 随机数逻辑有问题:你现在的
rand()+time(NULL)生成随机数的方式不对,而且每次循环都调用time(NULL)会导致同一秒内的随机数变化不大;更重要的是,随机数不会考虑已经缩小的范围,所以必然会重复猜已经被排除的数。 - 范围更新错误:当用户说目标数字比当前猜测大(
>)时,你把minimum设为numGen,但其实numGen已经被排除了,应该设为numGen + 1;同理,用户说更小(<)时,maximum应该设为numGen - 1,不然会重复猜同一个数。
修改后的代码(用二分查找替代随机)
#include <stdio.h> // 不需要stdlib.h和time.h了,因为不用随机数啦 int main() { int numGen; int minimum = 1; int maximum = 0; char answer; char answer2; // 获取合法的数值范围 while(minimum > maximum || minimum == 0){ printf("Insert range 'min-max'\n"); scanf("%d-%d", &minimum, &maximum); if(minimum <= maximum && minimum > 0) { break; } else { printf("Invalid range\n\n"); } } printf("Okay, think of your number in %d-%d!\n", minimum, maximum); while(1) { // 用二分法取中间值,避免重复猜测 numGen = minimum + (maximum - minimum) / 2; // 防止整数溢出,也可以写成 (minimum + maximum) / 2,但前者更安全 printf("Is your number: %d? (y/n)\n", numGen); scanf(" %c", &answer); if(answer == 'y') { printf("\nI guessed it! 🎉\n"); break; } else if(answer == 'n') { printf("Is it bigger (>), or smaller (<)?\n"); scanf(" %c", &answer2); if(answer2 == '>') { // 目标数比当前大,所以当前数可以排除,minimum更新为numGen+1 minimum = numGen + 1; } else if(answer2 == '<') { // 目标数比当前小,当前数排除,maximum更新为numGen-1 maximum = numGen - 1; } else { printf("Invalid input! Please enter '>' or '<'\n"); continue; } // 检查用户是否可能撒谎(范围不合理) if(minimum > maximum) { printf("Wait a minute, your answers don't add up! Are you sure you're telling the truth? 😜\n"); break; } } else { printf("Invalid input! Please enter 'y' or 'n'\n"); continue; } } return 0; }
为什么这个修改能解决问题?
- 二分法猜中间值:每次都猜当前有效范围的中间数,绝对不会重复猜已经被排除的数——因为范围会随着用户的回答动态缩小,每次的中间值都是新的有效范围内的数。
- 正确更新范围:当用户说“更大”,我们把最小值设为当前猜测+1,彻底排除当前数;说“更小”则把最大值设为当前猜测-1,同样排除当前数,确保范围里的数都是未被排除的。
- 增加健壮性:加入了对非法输入的判断,以及用户撒谎的检测(当最小值大于最大值时,说明逻辑矛盾)。
用你给的例子测试一下:
输入范围30-40,目标数字37:
- 第一次猜
30+(40-30)/2=35,用户回答n,然后说>,范围变成36-40 - 第二次猜
36+(40-36)/2=38,用户回答n,然后说<,范围变成36-37 - 第三次猜
36+(37-36)/2=36,用户回答n,然后说>,范围变成37-37 - 第四次猜37,用户回答
y,程序猜对!
完全不会出现重复猜40的情况,而且效率超高!
内容的提问来源于stack exchange,提问作者user14356197
相关产品推荐
相关产品推荐

