C语言人机猜数问题
问题描述
由计算机随机产生一个四位整数,请人猜这四位整数是多少。人输入一个四位数后,计算机首先判断其中有几位猜对了,并且对的数字中有几位位置也正确,将结果显示出来,给人以提示,请人再猜,直到人猜出计算机随机产生的四位数是多少为止。例如:计算机产生一个四位整数“1234”请人猜,可能的提示如下。
人猜的整数计算机判断有几个数字正确,有几个位置正确:
1122 2A1B
3344 2A1B
3312 3A0B
4123 4A0B
1243 4A2B
1234 4A4B
游戏结束。请编程实现该游戏。
问题分析
判断相同位置上的数字是否相同不需要特殊的算法。只要截取相同位置上的数字进行比较即可。但在判断几位数字正确时,则应当注意:计算机随机产生的是“123”,而人所猜的是“1576”,则正确的数字只有1位。程序中截取计算机随机产生的数中的每位数字与人所猜的数字按位比较。若有两位数字相同,则要记住所猜中数字的位置,使该位数字只能与一位对应的数字“相同”。当截取下一位数字进行比较时,就不应再与上述位置上的数字进行比较,以避免所猜的数中的一位与对应数中多位数字“相同”的错误情况。
随机数
随机数,顾名思义就是随机产生的、无规则的数。在编程中,有时不想手动从键盘输入数据,而想让电脑自动产生一些数据供使用(例如生成100个两位数),这时就要用到随机数。随机数的生成方法很简单,在TC环境下,通过调用随机函数random(n)来产生随机数。ramkom(n)函数是C语言的标准库函数,和常用的输入输出函数(scanf和printf) 一样可以在程序中直接调用。
random(n)函数的用法为:首先在程序开头预处理命令部分加l
#include<stdlib.h>
,其中<stdlib.h>是C中的标准库头文件,在使用random(n)函数时需要用到这个头文件。它的作用是对random(n)函数进行引用性声明,以便在下面的程序中使用它。这和在使用scanf()和printf()函数吋需要在程序开头写上
#include<stdio.h>
(标准输入/输出头文件)是一样的。然后在main()函数中使用randomize();
语句把随机数系统初始化。随机函数random(n)使用的格式为:
A= random(n);
这条语句的意思是,自动产生一个以0为下限,以n〜1为上限的随机数,并把值赋给A。例如,有如下语句:
int a;
a=random(90)+10;
a=random(100);
的区别。执行这条语句,a可能取值的上限同样为99,但下限为0,a可以取到10以下的数。相当于:
a=random(100)+0;
在VC环境下,随机数使用稍有不同。首先在main的前面用include包含文件 windows.h,即#include < windows.h>
,然后在main中用srand();
语句把随机数系统初始化,括号中放一个初始数据,为了模拟随机的效果,可以用当前的时间作为括号中的初始数据,例如:
srand(GetCurrentTime());
最后使用rand()函数产生一个随机整数。随机函数mnd()的每一次调用,都可得到一个很可能不同于上一次调用时的值,其取值一般在0〜65535之间。66536个整数值每一个值出现的几率都几乎相同。
注意rand()函数调用的两个特点:第一,调用时不需要参数,即函数调用时用rand(),圆括号中不必填入实际参数;第二,每次函数调用返回的值,从表面上看起来是不确定的,即是伪随机的,但实际上是有周期性的,只是这个周期比较大。
随机函数rand()使用的格式为:
A=rand()%x+y;
这条语句的意思是,自动产生一个以y为下限,以为上限的随机数,并把值赋给A。即A为y到x+y-1之间的随机数。例如,有如下语句:
int a;
a=rand()%90+10;
a=rand()%100;
的区别。执行这条语句,a可能取值的上限同样为99,但下限为0,a可以取到10以下的数。相当于:
a=rand()%100+0;
程序流程图:
下面是完整的代码:
#include<stdio.h> #include<time.h> #include<stdlib.h> int main() { int stime, a, z, t, i, c, m, g, s, j, k, l[4]; /*j:数字正确的位数 k:位置正确的位数*/ long ltime; ltime=time(NULL); /*l:数字相同时,人所猜中数字的正确位置*/ stime=(unsigned int)ltime/2; srand(stime); if( (rand()%10000) >= 1000 && (rand()%10000) <= 9999 ) z=rand()%10000; /*计算机想一个随机数*/ printf("机器输入四位数****\n"); printf("\n"); for(c=1; ; c++) /*c: 猜数次数计数器*/ { printf("请输入你猜的四位数:"); scanf("%d", &g); /*请人猜*/ a=z; j=0; k=0; l[0]=l[1]=l[2]=l[3]=0; for(i=1; i<5; i++) /*i:原数中的第i位数。个位为第一位,千位为第4位*/ { s=g; m=1; for(t=1; t<5; t++) /*人所猜想的数*/ { if(a%10 == s%10) /*若第i位与人猜的第t位相同*/ { if(m && t!=l[0] && t!=l[1] && t!=l[2] && t!=l[3]) { j++; m=0; l[j-1]=t; /*若该位置上的数字尚未与其它数字"相同"*/ } /*记录相同数字时,该数字在所猜数字中的位置*/ if(i==t) k++; /*若位置也相同,则计数器k加1*/ } s/=10; } a/=10; } printf("你猜的结果是"); printf("%dA%dB\n", j, k); if(k == 4) { printf("****你赢了*****\n"); printf("\n~~********~~\n"); break; /*若位置全部正确,则人猜对了,退出*/ } } printf("你总共猜了 %d 次.\n",c); return 0; }运行结果:
机器输入四位数****
请输入你猜的四位数:1234↙︎
你猜的结果是3A1B
请输入你猜的四位数:4091↙︎
你猜的结果是2A2B
请输入你猜的四位数:3766↙︎
你猜的结果是1A0B