给出洗牌的一个算法
并将洗好的牌存储在一个整形数组里 问题点数:50、回复次数:19Top
1 楼steedhorse(晨星)回复于 2005-04-12 21:04:21 得分 1
STL的random_shuffle?Top
2 楼steedhorse(晨星)回复于 2005-04-12 21:05:49 得分 2
从第一张牌(n = 1)开始,每次产生一个n到54之间的一个随机下标i,然后把第n张牌和第i张牌互换。Top
3 楼pcboyxhy(-273.15℃)回复于 2005-04-12 21:28:01 得分 1
不会打牌
呵呵Top
4 楼takbj(剑之吻)回复于 2005-04-12 21:36:10 得分 1
EZ!Top
5 楼ljq14(冷爱)回复于 2005-04-12 21:48:30 得分 1
跟我的一样~~~
唉
Top
6 楼0011411(爱也许是假的,可是当时的快乐是真的。)回复于 2005-04-12 21:56:35 得分 0
晕!洗牌好象很难哦Top
7 楼chunhai12(小海)回复于 2005-04-12 22:23:11 得分 1
楼主是指模拟洗牌的过程还是只要洗牌的效果
如果只要洗牌的效果那就直接重排不就行了Top
8 楼CJLL0218(CJ_C\C++)回复于 2005-04-12 22:27:48 得分 5
设置一个类,里面有4个变量,一个放花色,一个放点数,2个计数器;
NEW 一个该类的对象;
设置一个时间类型的变量,作为种子,得到随机数(X)后 (X MOD 4) + 1(保证它在1至4之间),放到花色里,然后 花色计数器 +1(每个花色有12张,所以计数器要小于12);
设置一个数组P,里面放上1至12,然后随机取,取一个 标示下标的变量(注意:不是下标+1,是标示下标的变量,也就是计数器) +1(不能大于4,等于4的时候重新随机),然后放到类的点数变量里;
将NEW出来的类压到一个vector里;
释放NEW;
完成一张牌!
循环,直到P里每个下标的标示都是4了,结束,54张就OK,vector里放的就是54张分花色分大小的牌!
Top
9 楼du51(郁郁思扬)回复于 2005-04-12 23:04:48 得分 13
#include<iostream>
using namespace std;
struct pukepai{
char d; //点
char s; //花色
};
char dian(int i)
{
switch(i)
{
case 0: return 'K';
case 1: return 'A';
case 11: return 'J';
case 12: return 'Q';
default: return i+48;
}
}
char spe(int i)
{
switch(i)
{
case 0: return 3; //红
case 1: return 4; //方
case 2: return 5; //梅
case 3: return 6; //黑
}
}
void display()
{
pukepai p[54];
int temp[54],tem,i,j;
for(i=0;i<54;i++)temp[i]=i+1;
srand(time(0));
for(i=0;i<54;i++) //洗牌 1---54的随机数
{
tem=rand()%54;
j=temp[i];
temp[i]=temp[tem]; //要是以整数存,此处即可.
temp[tem]=j;
}
for(i=0;i<54;i++) //赋值 并显示
{
if(temp[i]==54)p[i].d='S',p[i].s=0; //大S
else if(temp[i]==53)p[i].d='s',p[i].s=0; //小s
else
{
p[i].d=dian(temp[i]%13);
p[i].s=spe((temp[i]-1)/13);
}
cout<<p[i].s<<p[i].d<<" "; //显示用于测试 10为: 也可以不这样.修改前面.
}
cout<<endl;
}
int main()
{
display();
system("PAUSE");
return 0;
}Top
10 楼du51(郁郁思扬)回复于 2005-04-12 23:07:26 得分 10
#include<iostream>
using namespace std;
struct pukepai{
char d; //点
char s; //花色
};
char dian(int i)
{
switch(i)
{
case 0: return 'K';
case 1: return 'A';
case 11: return 'J';
case 12: return 'Q';
default: return i+48;
}
}
char spe(int i)
{
switch(i)
{
case 0: return 3; //红
case 1: return 4; //方
case 2: return 5; //梅
case 3: return 6; //黑
}
}
void display()
{
pukepai p[54];
int temp[54],tem,i,j;
for(i=0;i<54;i++)temp[i]=i+1;
srand(time(0));
for(i=0;i<54;i++) //洗牌 1---54的随机数
{
tem=rand()%54;
j=temp[i];
temp[i]=temp[tem]; //要是以整数存,此处即可.
temp[tem]=j;
}
for(i=0;i<54;i++) //赋值 并显示
{
if(temp[i]==54)p[i].d='S',p[i].s=0; //大S
else if(temp[i]==53)p[i].d='s',p[i].s=0; //小s
else
{
p[i].d=dian(temp[i]%13);
p[i].s=spe((temp[i]-1)/13);
}
}
for(i=0;i<54;i++)cout<<p[i].s<<p[i].d<<" "; //改成这样.上面的不行.
cout<<endl;
}
int main()
{
display();
system("PAUSE");
return 0;
}Top
11 楼chogo(尘埃落定)回复于 2005-04-13 00:43:42 得分 2
四种花色加大王小王一共是54张,那我可以开一个54的数组,把某个下标当作是某张牌,然后给数组赋随机数(1-54),然后排序……Top
12 楼archim(PRC)回复于 2005-04-13 09:06:04 得分 2
回复人: steedhorse(晨星) ( ) 信誉:119 2005-04-12 21:05:00 得分: 0
从第一张牌(n = 1)开始,每次产生一个n到54之间的一个随机下标i,然后把第n张牌和第i张牌互换。
===================================================
这个算法不错,不过可以改进一下,每次产生2个下标,然后这2张牌互换Top
13 楼wachel(大脚)回复于 2005-04-13 09:49:05 得分 2
我以前是这样做的
产生一个1到54的随机数,将这张牌放到目标数组。然后将第54张复制到这个位置。
产生一个1到53的随机数,。。。。。。。。。。。。。。。53。。。。。
。。。。。 52
。。。。。 51
我觉得这样应该挺快的了
Top
14 楼inlin()回复于 2005-04-13 13:00:43 得分 1
srand(time(0));
这有什么用
好象不能起到每次都不同的结果啊Top
15 楼jingyueid(干宁)回复于 2005-04-13 13:32:49 得分 2
strand(time(0));
是使用当前时间数随机种子数,每次都不会相同。
楼主只要不是采用,将随机数字作为牌来填充就成。
(如果只是使用随机数来填充,比较数字是否被占用,否则重新随机数字是很容易造成stack overflow,偶是有过这种痛苦经历的。)Top
16 楼gumbour(gub不是bug)回复于 2005-04-13 16:20:03 得分 3
54张牌存在一个54个空间的数组里
生成54个1-54的随机数
第i个元素与第i个随机数为下表的数组元素交换Top
17 楼TemplatesGuy(勤学苦练,一切皆有可能,某人马甲每天深夜到1点)回复于 2005-04-13 17:01:08 得分 1
mkTop
18 楼bbdog(贝贝狗)回复于 2005-04-13 17:49:30 得分 1
这个问题的关键是效率问题,二楼的回答可以有效的洗好牌,不会出现无穷延时问题,循环54次后,牌就洗好了。Top
19 楼czytf(天上有)回复于 2005-04-13 19:14:18 得分 1
good
Top




