要處理這些卡片,您應該在洗牌後取出頂牌。
如果您想要隨意選擇一個隨機項目(或無混洗),您可以通過選擇該範圍內的隨機索引,然後從該數組中刪除該項目來實現。要選擇第二個項目,您再次選擇一個隨機索引(在現在縮小的範圍內),然後刪除該項目。
此外,您的shuffle算法不正確。它看起來像你試圖解決通常的問題(why does this simple shuffle algorithm produce biased results? what is a simple reason?),但有一個錯字。您的代碼int r = i + (rand() % (52-1))
應該是int r = i + (rand() % (52-i))
。 52-i
,而不是52-1
。該錯誤會導致您可能訪問數組邊界之外。我認爲你的卡片交換代碼也有一個錯字。
當然rand()
通常是一個不好的隨機數據來源。 <random>
庫更好,更易於使用。
我將展示兩個版本的示例解決方案,一個使用<random>
,另一個使用rand()
。 <random>
就是你應該做的,但是我會顯示rand()
只是爲了保持與代碼的差異最小化。
#include <random>
std::vector<int> cards(52);
// fill the array
std::iota(std::begin(cards), std::end(cards), 0);
// std::shuffle(std::begin(cards), std::end(cards), eng);
std::default_random_engine eng;
std::uniform_int_distribution<int> dist;
// select 10 cards
for (int i=0; i<10; ++i) {
// select a random index in the range [0, cards.size()-1]
int card_index = dist(eng, {0, cards.size()-1});
int card = cards[card_index]; // get the card and do something with it
cards.erase(std::begin(cards) + card_index); // remove the card from the deck
}
int n = 52;
int cards[52];
// select 10 cards
for (int i=0; i<10; ++i) {
int card_index = rand() % n;
int card = cards[card_index]; // get the card
// remove the card from the deck
--n;
card[card_index] = card[n];
}
如果卡片已經隨機的,沒有必要從列表中選擇一個隨機卡。 – Almo
我意識到這一點,但它更多的是學習類型的東西。我非常想知道如何從已定義的數組中提取隨機索引。我應該在我的文章中提到,對不起。 – user3435029
你的意思是你想從[0,51]中選擇一個隨機數嗎?或者給定一個數字,比如10,你想把'cards [10]'的值賦給另一個變量?或者你也想修改數組,也許通過刪除'cards [10]'並以某種方式重新排列其他元素? – Beta