17功能之使用STL容器实现洗牌算法(全局与局部)
1 洗牌算法
1)全局。每次的概率都保持一样。例如54张牌,需要放54次。每次都是1/54的概率随机抽取一张,放在0-53的下标中去。
2)局部。每次随机抽取一张牌后放在第一个位置,放好的不再处理,然后再从剩下的牌随机抽取放在第一位(相对),共n-1次放完。
2 代码实现
1)全局
//全局(重复、等概率)洗牌
//cardNum代表产生的牌数
vector<int> Make_Random_Cards1(int cardNum) {
srand((unsigned)time(NULL));
vector<int> v;
//先往数组存放1-cardNum的元素
for (int i = 0; i < cardNum; i++) {
v.push_back(i + 1);
}
//洗牌
for (int i = 0; i < cardNum; i++) {
int rd = rand() % cardNum; // 每个牌数的概率都是1/cardNum
Swap(v[i], v[rd]);
}
return v;
}
2)局部
//局部(不重复)洗牌
vector<int> Make_Random_Cards2(int cardNum) {
srand((unsigned)time(NULL));
vector<int> v;
//先往数组存放1-cardNum的元素
for (int i = 0; i < cardNum; i++) {
v.push_back(i + 1);
}
//STL的库函数洗牌
//random_shuffle(v.begin(), v.end());
//洗牌 每次随机抽取一张放在第一位
for (int i = 0; i < cardNum - 1; i++) {
int rd = rand() % (cardNum - 1 - i) + (i + 1);
Swap(v[i], v[rd]);
}
return v;
}
3)额外添加一个斗地主算法
//实现斗地主
void DouDiZhu()
{
srand((unsigned)time(NULL));
int total[54]; //存储54张牌的数组
int player[3][17];//存储三个玩家的牌
int leftNum = 54; //存储当前剩余牌的数量
int randNumber; //随机数字
// 给数组添加1-54的牌
for (int i = 0; i < 54; i++)
{
total[i] = i + 1;
}
//循环发牌(关键)
for (int i = 0; i < 17; i++) {
for (int j = 0; j < 3; j++) {
randNumber = rand() % leftNum;
player[j][i] = total[randNumber]; //依次为每个人一张一张的发牌
total[randNumber] = total[leftNum - 1]; //移动已经发过的牌,即将最后的牌往已经发过的位置覆盖
leftNum--; //可发牌的数量减少1
}
}
//循环输出玩家手中的牌
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 17; j++) {
cout << " " << player[i][j];
}
cout << endl;
}
//底牌
for (int i = 0; i < 3; i++) {
cout << " " << total[i];
}
cout << endl;
}
void MyPrit(int v) {
cout << v << " ";
}