原题目:
程序随机生成4个 0到 9之间的整数,作为神秘数字。玩家通过反复的猜测找到这4个数。并且要求先后顺序也要正确,数值和位置都正确是公牛,数值正确,位置不对是母牛。
例如:神秘数字是 1234 ,而玩家猜测的是 1355,程序的反馈结果是“一头公牛 一头母牛”。
通过网上的资料追加要求:如果相同的母牛重复出现多次只能算一个母牛,不能重复计次。
例如:神秘数字是 1234 ,玩家猜测的是 2222,程序的反馈是“一头公牛 一头母牛”,而不是“一头公牛 三头母牛”。
解题思路:
1,为了方便玩家对4个数字的输入,可以把数字存储为字符串类型,这样数字输入时中间不用留空格,能一次性对4个数字全部读取。
2,公牛和母牛很容易辨别,关键是相同的母牛多次出现只能计一次,不能重复计次。
3,为了避免相同母牛的重复计次,只需要在确定该数值是母牛后,把神秘数字里面与该值相同的数屏蔽掉,这样下次再遇到这个数值时就会跳过,不会重复计次了。
4,屏蔽时为了不改变其它数值的位置,可以把该值设置为0到9以外的任意一个字符(我设为一个空格)。
5,第3,4步修改的不能是神秘数字的原数据,因为这样会对公牛的确认造成麻烦,所以要有一个神秘数字的复本,确认母牛时和神秘数字的复本比较,确认公牛时直接和原数据比较。
特别提醒:本代码只是简单的暴力求解,不含任何算法,不含任何特殊的数据结构。因为我是新手,网上那些什么哈希表等方法,我都是看不懂的。
代码如下:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<stdexcept>
#include<ctime>
#include<cstdlib>
#include<cstdio>
#include<limits>
using namespace std;
int get_niu(string secret,string guess) //计算公牛和母牛数量的函数
{
int ox,cow;
ox=cow=0;
string c;
c=secret;
for(int i=0; i<4; i++)
{
if(guess[i]==secret[i]) //和secret字符串比较,来确定公牛
ox++;
else
{
for(int n=0; n<4; n++) //不是公牛就和secret的复本c比较,来确定是否是母牛
{
if(guess[i]== c[n]) //如果是母牛,则母牛数量+1,并且再次遇到这个值时跳过检测
{
cow++;
c[n]=' ';
for(int j=n+1; j<4; j++)
if(c[j]==guess[i])
c[j]=' ';
break;
}
}
}
}
if(ox==4)
cout<<"\n4头公牛\n";
else
cout<<endl<<ox<< "头公牛 "<<cow<< "头母牛\n";
return ox;
}
int main()
{
cout<<"\t\t公牛和母牛\n\n";
srand(time(NULL)); //置随机数种子
cout<< "输入任意字符开始游戏,q退出\n";
char n;
while(cin>>n)
{
cin.ignore(numeric_limits<streamsize>::max(),'\n'); //清空输入行
if(n=='q')
return 0;
string secret;
for(int i=0; i<4; i++) //设置4个随机数 并存储为secret字符串
secret+= char(rand()%10+48);
cout<<"显示本局的神秘数字,便于调试程序\n";
cout<<"神秘数字为:"<<secret<<"\n\n";
cout<< "是哪4个数?请输入(数字之间不要空格):";
string guess;
while(1)
{
cin>>guess;
cin.clear(); //清除cin的错误标记
cin.sync(); //清空输入缓冲区
if(guess.size()!=4)
{
cout<< "长度不对,请重新输入(4个数字之间不留空格):";
continue;
}
if(get_niu(secret,guess)==4)
break;
cout<< "再猜(数字之间不要空格):";
}
cout<< "\n恭喜你全部猜中!输入任意字符开始下一局,q退出\n";
}
}
新知识总结:
1,cin.clear() 清空 cin 的错误标记
cin.ignore(numeric_limits<streamsize>::max(),'\n') 清空输入行
cin.sync() 清空输入缓冲区
2,参数为向量的函数声明: void abc(vector<int>& a,vector<char>& b)
引用时格式: abc(a,b) 其中a,b为向量。
3,string abc abc就是一个空字符串
abc= "Hello world"
string efg
efg= abc efg内容是“Hello world” ,在不改变 efg 数据的时候,efg 指向的内存地址和 abc 内存地址相同 (浅复制)
只有在改变efg 数据时,才会真正复制abc 的内容到新的 内存地址,不改变abc原数据。
4,random(n) 取随机数 范围:0到 n-1 之间
random(m,n) 取随机数 范围:m 到 n-1 之间 ,需要编译器支持C++11 标准。