原題目:

程式隨機生成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 標準。

.