来者有分,今天的一道面试题
今天面试,一道程序设计题,实现发牌算法。一共52张牌,没有大小王。我大概作了一下,下面的是我后来后整理的完整版本,和我面试的时候差不多。不能够使用STL。
#include<iostream>
using namespace std;
struct PK_Link
{
char *PK;
PK_Link *next;
} *Header, *ptr;
void CreatePK( char *p )
{
Header = new PK_Link;
Header->PK = p;
Header->next = NULL;
ptr = Header;
}
void AddPK( char *p )
{
PK_Link *PK = new PK_Link;
PK->PK = p;
PK->next = Header;
ptr->next = PK;
ptr = ptr->next;
}
char* FindPK( int i )
{
while( i > 0 )
{
--i;
ptr = ptr->next;
}
return ptr->next->PK;
}
void DeletePK()
{
PK_Link *t = ptr->next;
ptr->next = ptr->next->next;
delete t;
}
void DestroyPK()
{
delete ptr;
}
char *PKD[52] = {
"黑桃A", "红桃A", "方块A", "梅花A",
"黑桃2", "红桃2", "方块2", "梅花2",
"黑桃3", "红桃3", "方块3", "梅花3",
"黑桃4", "红桃4", "方块4", "梅花4",
"黑桃5", "红桃5", "方块5", "梅花5",
"黑桃6", "红桃6", "方块6", "梅花6",
"黑桃7", "红桃7", "方块7", "梅花7",
"黑桃8", "红桃8", "方块8", "梅花8",
"黑桃9", "红桃9", "方块9", "梅花9",
"黑桃10", "红桃10", "方块10", "梅花10",
"黑桃J", "红桃J", "方块J", "梅花J",
"黑桃Q", "红桃Q", "方块Q", "梅花Q",
"黑桃K", "红桃K", "方块K", "梅花K"
};
char *Persion[4][13] = {0};
int main( int argc, char *argv[] )
{
int i = 0, j = 0, k = 0;
CreatePK( PKD[0] );
for ( ; i < 51; i++ )
{
AddPK( PKD[i] );
}
i = 52;
while( i > 1 )
{
Persion[j][k] = FindPK( rand() % i );
DeletePK();
--i;
++j;
if ( j > 3 )
{
++k;
j = 0;
}
}
Persion[3][12] = FindPK( 1 );
for ( j = 0; j < 4; j++ )
{
cout<<"Persion["<<j+1<<"]";
for( k = 0; k < 13; k++ )
{
cout<<" "<<Persion[j][k];
}
cout<<endl;
}
DestroyPK();
return 0;
}
大家看看,我能通过吗?谁还有更好的算法!
问题点数:100、回复次数:72Top
1 楼qfeng_zhao(鱼儿鱼儿满天飞)回复于 2005-07-13 21:10:08 得分 1
没问题Top
2 楼durkingzhang(永胜)回复于 2005-07-13 21:46:15 得分 1
虽然没有错误,但是一般!!!!!!Top
3 楼AntonlioX(做人要厚道)回复于 2005-07-13 21:47:29 得分 1
markTop
4 楼chengjr(小小)回复于 2005-07-13 21:51:58 得分 1
你从来不写注释的吗
我实在不想看没注释的代码,好歹也说说你的思路Top
5 楼yangbc(土豆块)回复于 2005-07-13 21:53:40 得分 1
没看你的程序,不过你只要用了随机数就应该差不多了,只要从前往后把数组中的牌跟一个随机出现的位置的牌互换,然后再把这些牌发到玩家手中就可以了Top
6 楼god_sun(蹲在厕所逗蛆玩)回复于 2005-07-13 21:57:31 得分 1
是啊 ,楼主写写注释吧:)Top
7 楼WecanHuang(曾阿牛)回复于 2005-07-13 22:05:04 得分 1
现在的面试。。。Top
8 楼K()回复于 2005-07-13 22:12:12 得分 1
怎么发都是一样的牌Top
9 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-13 22:16:29 得分 0
我在面试的卷子上写了设计思路!
使用一个单向循环链表,从头指针开始,随机向前移动,取出牌,删除这个节点,然后继续作。直道取出52张牌!Top
10 楼boxban(冻酸梨)回复于 2005-07-13 22:19:28 得分 10
恕我直言,你的实现从功能上可能没有问题,但代码实现也有点太罗嗦了。
你没有详细说明题目,不知道除了STL,还有没有其他限制?是不是指定了必须要使用链表来实现?
如果仅仅是实现“将不含大小王的52张扑克牌随机发给4个人,并显示发牌的最终结果”的功能,应该是很简单的。代码应该可以实现得更简洁、高效。
下面是我的一个实现。
另外,楼主在开始没有调用srand()设置随机种子,导致楼上所说的“怎么发都是一样的牌”的问题。
=========================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//
// 我给出的是一种相对节省“空间”的实现。
// 如果将52张牌的花色、名称全部保存在数组中(如楼主的实现),
// 则可以简化牌面的显示并获得最大的运行时性能。
//
//数字 0~51 代表52张扑克牌。
//每连续13张为同一花色的13张牌,如黑桃A~黑桃K(如 CARD_NAME 定义)。
//花色以 "黑桃", "红桃", "方块", "梅花" 顺序排列(如 COLOR_NAME 定义)
//
static const char* CARD_NAME[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
static const char* COLOR_NAME[] = { "黑桃", "红桃", "方块", "梅花" };
static const int COLORS = sizeof(COLOR_NAME)/sizeof(COLOR_NAME[0]);
static const int CARDS = sizeof(CARD_NAME)/sizeof(CARD_NAME[0]);
static const int N = 52;
static const int CARD_USED = 0;
//发牌
void dispatch_cards(int out[N])
{
int cards[N];
int i, t;
for (i = 0; i < N; ++i) cards[i] = i + 1; //设置牌号
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
}
//显示牌面
void show_cards(const int cards[N])
{
int i, j;
//0~12, 13~25, ... 分别存放4个人牌
for (i = 0; i < N;){
printf("\nPerson %d: ", i / CARDS + 1);
for (j = 0; j < CARDS; ++j, ++i)
printf("%s%s, ", COLOR_NAME[cards[i] / CARDS], CARD_NAME[cards[i] % CARDS]);
}
}
int main(int argc, char agrv[])
{
int cards[N];
srand(time(NULL));
dispatch_cards(cards);
show_cards(cards);
return 0;
}
Top
11 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-13 22:46:46 得分 0
兄弟,空间效率有了,时间效率差了!Top
12 楼vsfan(窘)回复于 2005-07-13 23:28:20 得分 1
呵呵
其实数组也可以模拟的Top
13 楼MagicCarmack(MagiC++)回复于 2005-07-13 23:30:30 得分 1
数组模拟可行Top
14 楼wiali(维埃里)回复于 2005-07-14 00:29:58 得分 1
我觉得应该考的是随机算法的编写,而不掉系统函数显示一下那么简单。Top
15 楼wiali(维埃里)回复于 2005-07-14 01:11:58 得分 3
我认为时间效率肯定是boxban(冻酸梨)的高,这个链表分配查找和删除肯定没数组来得快。
另外我觉得boxban(冻酸梨)写的非常简洁,而且没有hardcode,相比之下,楼主hardcode很明显.
挺佩服boxban(冻酸梨)的代码的,找了半天没找到一句废码,唯一可以改进的地方就是:
static const int CARD_USED = 0; =》static const int CARD_USED = 1;
int cards[N]; =》int cards[N]={0};
最后 for (i = 0; i < N; ++i) cards[i] = i + 1; 这句话就可以不要了,这样还可以省掉一句话。
我也就是瞎扯,大家只当听个乐呵!
Top
16 楼mayingbao(卖烧烤的鱼)回复于 2005-07-14 06:13:13 得分 1
你没有详细说明题目,不知道除了STL,还有没有其他限制?是不是指定了必须要使用链表来实现?
如果仅仅是实现“将不含大小王的52张扑克牌随机发给4个人,并显示发牌的最终结果”的功能,应该是很简单的Top
17 楼sea2000cn(我想我是海)回复于 2005-07-14 07:22:21 得分 1
用数组模拟是不是更快?Top
18 楼aayy(以后我不用这个名字了)回复于 2005-07-14 08:28:48 得分 1
做个标记Top
19 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 08:49:30 得分 0
感谢大家!boxban的方法固然不错,但是还是有很多缺陷,并不是最优解法。还有其他人吗?Top
20 楼sy_lyx(沈阳之最)(阿轩)回复于 2005-07-14 08:59:39 得分 1
No problem.Top
21 楼lonelyforest(一生所爱)回复于 2005-07-14 09:14:28 得分 1
老兄们啊, 为什么不用类呢??Top
22 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 09:34:34 得分 0
我给的基本上就是原题了,大家自由发挥!Top
23 楼boxban(冻酸梨)回复于 2005-07-14 09:48:13 得分 1
感谢大家!boxban的方法固然不错,但是还是有很多缺陷,并不是最优解法。还有其他人吗?
===================================================================================
首先感谢楼主的表扬,呵呵。
对于很多问题,多数情况下并不存在所谓的“最优解法”。我想大家都知道“时间换空间,空间换时间”的法则;对于不用的应用环境、硬件环境,可能需要采取不同的策略。
我的实现采取了“时间换空间”的策略,相对于将52张牌面全部保存在数组的解法而言虽然节省的空间只有区区几十个字节,但理还是这个理,呵呵
楼主称我的方法有很多缺陷,能否具体讲讲?死也得让我死个明白呀 ^_^Top
24 楼login__whf(还买烟不*_*)回复于 2005-07-14 10:19:33 得分 1
upTop
25 楼xuanwenchao(xuanwenchao)回复于 2005-07-14 10:43:41 得分 1
我觉得boxban(冻酸梨)的算法已经不错了.Top
26 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 10:48:58 得分 0
to boxban
是这样的,作为随机数,是允许有重复值出现的,那么在这里
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
必然会浪费一些时间,而且这个时间浪费还会随着i值的不断增大而增大,因为可用的太少了。
是否考虑N要变化,把它规定在一个符合52-i内的范围之内,这样会避免一些时间浪费!
这是我对你的程序的一点分析!Top
27 楼syg1()回复于 2005-07-14 11:11:14 得分 5
#include <iostream.h>
int Poker[52];
//½«start+1µ½endµÄÅÆÏòÇ°ÒÆ¶¯Ò»Î»
void movepoker(int Poker[],int start,int end)
{
int i=0;
for (i=start;i<end-1; i++)
{
Poker[i]= Poker[i+1];
}
}
void dispatch() //Poker[52]ÖÐ--->0-12 ÊǵÚÒ»¸öÈË 13-25Êǵڶþ¸öÈË 26 - 38ÊǵÚÈý¸öÈË 39 - 51 ÊǵÚËĸöÈËµÄ ÅÆ
{
int i=0;
int rand=0;
int pokernum = 52;
int index =0;
int Tpoker[52];
//½«52ÕÅÅÆ·ÅÈëÊý×éTpokerÖÐ,·¢ÅƵÄʱºò´ÓÖÐÈ¡³ö
for(i=0;i<pokernum;i++)
{
Tpoker[i] = i;
}
//start to ·¢ÅÆ
index =0;
while(pokernum){
rand = rand();
rand %= pokernum; //ÔÚ0µ½pokernum-1²úÉúÒ»¸öËæ»úÊý
Poker[index++] = Tpoker[rand]; //È¡³öÔÚ´Ë´¦µÄÊý×Ö
//randλÖõÄÅÆÒѾ­È¡³ö,½«rand+1µ½pokernum-1ÏòÇ°ÒÆÒ»Î»
movepoker(Tpoker,rand,pokernum-1);
//Ê£ÓàµÄÅÆÊý¼õ1
pokernum--;
}
}Top
28 楼junnyfeng(风歌)回复于 2005-07-14 11:11:14 得分 1
boxban(冻酸梨) 的程序比较巧妙,是让人有耐心去看的程序!Top
29 楼junnyfeng(风歌)回复于 2005-07-14 11:12:19 得分 1
搂主是不是姓邓?Top
30 楼iamltd(妖)回复于 2005-07-14 11:15:07 得分 1
生成随机数那里是需要技巧的
循环改成:
i=N-1;
do{
t=(rand() % i--);c=0;
do{
if(cards[c] !=CARD_USED)c++;
}while(c<t)
cards[c] = CARD_USED;
out[i]=t;
}while(i>=0)
这样处理以后,每次生成的随机数不再是牌的序号,而是未发的牌的序号。可以保证不会产生冲突。
理论上的时间效率很低,实际运行中应该是最优时间算法了。
--------------------------------------------
语法上大概没错吧。呵呵,我一向记不清语法的。Top
31 楼boyu_song(我这样会不会遭天谴,我只是想看看这个论坛的ID最大可以多大?)回复于 2005-07-14 11:15:47 得分 1
I'm use the JAVA,and this program ,you can use the JAVABEAN,that will be easier~Top
32 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 11:27:55 得分 0
to junnyfeng(风歌) 为什么怎么问?Top
33 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 11:29:42 得分 0
我不姓邓阿!Top
34 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 11:34:51 得分 0
to iamltd(妖)
你的程序有错误!
因为使用了随机数,不能随意作i--,所以你的程序发不出52张牌!Top
35 楼simec(simec)回复于 2005-07-14 11:35:11 得分 1
gzTop
36 楼yvhkdragon(剑客)回复于 2005-07-14 12:24:06 得分 1
UPTop
37 楼netfloator(Adam Lee)回复于 2005-07-14 12:39:20 得分 1
AddPK中好像有问题,字符串赋值要用strcpy,直接用指针赋值会有问题。
还有*PKD[52]数组不用罗列出来,可以在程序中给他们赋值。
存储扑克可以用顺序表,删除牌时,不必用顺序表的删除算法,只要把这个元素与第i(就是你程序中用到的i)个元素交换即可。Top
38 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 13:08:40 得分 0
楼上的,这只是对指针操作。
如果在程序中赋值的话,简单的指针操作就不行了!Top
39 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 13:10:54 得分 0
你那个交换的方法非常好!呵呵!还有谁阿!~Top
40 楼qingyuan18(zealot_tang)回复于 2005-07-14 13:40:27 得分 1
boxban(冻酸梨)的发排方法相当于每个人从洗好的牌中随机抽13张,而jiajun2001 (嘉俊) 的发排方法是最常见的四个人依次每人一张Top
41 楼sinall()回复于 2005-07-14 14:13:20 得分 1
其实就是STL中的洗牌算法,洗好了牌,大家一揭牌不就完事了。
凭直觉,感觉boxban(冻酸梨)的方法确实好,但也有提升时间复杂度的可能。
待俺去研究研究。Top
42 楼boxban(冻酸梨)回复于 2005-07-14 14:18:15 得分 1
to boxban
是这样的,作为随机数,是允许有重复值出现的,那么在这里
for (i = 0; i < N;){
t = (rand() % N);
if (cards[t] != CARD_USED){
cards[t] = CARD_USED;
out[i++] = t;
}
}
必然会浪费一些时间,而且这个时间浪费还会随着i值的不断增大而增大,因为可用的太少了。
是否考虑N要变化,把它规定在一个符合52-i内的范围之内,这样会避免一些时间浪费!
这是我对你的程序的一点分析!
========================================
"是否考虑N要变化,把它规定在一个符合52-i内的范围之内"
这是不可行的。
按照你的说法,假设第一次 t = 10, 然后 i++,在第二次循环时令 N = N - i = 51。
那么,你就再也没有机会取道51号扑克牌了
Top
43 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 14:49:00 得分 0
我只是这个意思,并不是一定那样,当然会出现你上面所说的问题了!Top
44 楼OMA_yudy(太平洋深深)回复于 2005-07-14 15:15:23 得分 15
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#define N 52
struct joke {
char p[4];
};
joke page[52] = {"S1","S2","S3","S4","S5","S6","S7","S8","S9","S10","S11","S12","S13",
"H1","H2","H3","H4","H5","H6","H7","H8","H9","H10","H11","H12","H13",
"D1","D2","D3","D4","D5","D6","D7","D8","D9","D10","D11","D12","D13",
"C1","C2","C3","C4","C5","C6","C7","C8","C9","C10","C11","C12","C13",};
void exchange(int a[])
{
srand( (unsigned)time( NULL ) );
int tmp,v;
for (int i=0;i<52;i++)
{
v = rand()%N;
if(i!=v){
tmp = a[v];
a[v] = a[i];
a[i] = tmp;
}
}
for (i=0;i<52;i++)
{
cout.width(3);
cout<<page[(a[i]-1)].p<<" ";
if (i==52 || i==12 || i==25 || i==38)
{
cout<<endl;
}
}
}
int main(int argc, char* argv[])
{
int na[52];
for (int i=0;i<52;i++)
{
na[i]=i+1;
}
exchange(na);
cout<<endl;
char tmp;
cin>>tmp;
return 0;
}
从浪费时间的角度出发Top
45 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 15:32:16 得分 0
OMA_yudy的差不多时间复杂度和空间复杂度有所保证了Top
46 楼hewittlee(只爱C++)回复于 2005-07-14 15:59:46 得分 1
不错!Top
47 楼seann_liu()回复于 2005-07-14 16:57:36 得分 3
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>
void shuffle ( int [] [13] );
int main()
{
const char *suit[4]={"Heart", "Diamonds", "Clubs", "spades"};
const char *face[13] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
int deck[4][13] = {0};
srand (time(0));
shuffle(deck);
deal (deck, face, suit);
return 0;
}
void shuffle (int wDeck[][13])
{
int row, column;
for (int card = 1; card <=52; card++){
do {
row = rand()%4;
column = rand()%13;
}while (wDeck[row][column] != 0);
wDeck[row][column] = card;
}
}
void deal (const int wDeck[][13], const char *wDeck[], const char *wSuit[])
{
for (int card = 1; card <=52; card++)
for (int row = 0; row <=3; row ++)
for (int column = 0; column <= 12; column++)
if (wDeck [row][column] == card)
cout << setw(5) << setiosflags(ios::right)
<< wFace[column] << "of"
<<setw(8) << setiosflags(ios::left)<<wSuit[row]
<< (card % 2 == 0 ? '\n' : '\t';
}Top
48 楼seann_liu()回复于 2005-07-14 17:27:37 得分 1
不过这个程序应该有一点点小毛病Top
49 楼foochow(无聊,灌水......)回复于 2005-07-14 17:33:28 得分 1
洗好牌在发出去?Top
50 楼seann_liu()回复于 2005-07-14 17:51:17 得分 1
no,是deal那个function....Top
51 楼tslkfyh(TSL)回复于 2005-07-14 18:31:19 得分 1
程序开始时把牌创建成一个链(供以后多次发牌使用)
使用一个记数器(如I=52)
产生大小在记数器范围内的随机数
根据此数在链中打位置(如标置了已发的不算一个位置 例如 1未发->2未发->3已发->4未发->5未发,现在随机数为3 找到的是4未发)发牌;
标致已发,记数器减一;
不知思路有没有用Top
52 楼seann_liu()回复于 2005-07-14 18:51:07 得分 1
思路是酱子,我没说思路,我的意思是我觉得我的代码的最后一部分好像有点小毛病...Top
53 楼yangwuhan()回复于 2005-07-14 19:00:09 得分 1
jfTop
54 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 20:05:37 得分 0
to seann_liu()
你的代码有做无用功的时候,跟boxban(冻酸梨)的一样!
目前OMA_yudy(太平洋深深) 的最好Top
55 楼jiangbo1125(江小鱼)回复于 2005-07-14 20:19:23 得分 1
是用链表实现的吗?Top
56 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 20:32:00 得分 0
我使用的单向循环链表Top
57 楼seann_liu()回复于 2005-07-14 20:34:36 得分 1
我知道有作无用功的时候,你能帮改一下吗?Top
58 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 20:56:59 得分 0
参考OMA_yudy(太平洋深深)的代码Top
59 楼seann_liu()回复于 2005-07-14 21:00:41 得分 3
或者这样:
#include <iostream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <time.h>
struct Card{
char *face;
char *suit;
};
void fillDeck (Card*, char *[], char *[]);
void shuffle(Card *);
void deal (Card *);
int main()
{
Card deck[52];
char *face[13] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
char *suit[] = {"Hearts", "Diamonds", "Clubs", "Spades"};
srand(time(0));
fillDeck (deck, face, suit);
shuffle(deck);
deal (deck);
return 0;
}
void fillDeck(Card *wDeck, char *wFace[], char *wSuit[])
{
for (int i = 0; i < 52; i++){
wDeck[i].face = wFace[i % 13];
wDeck[i].suit = wSuit[i / 13];
}
}
void shuffle (Card *wDeck)
{
for (int i = 0; i < 52; i++){
int j = rand() % 52;
Card temp = wDeck[i];
wDeck[i] = wDeck[j];
wDeck[j] = temp;
}
}
void deal (Card *wDeck)
{
for ( int i = 0; i <52; i++)
cout<< setiosflags(ios::right)<<setw(5)<<wDeck[i].face<<"of"<<setiosflags(ios::left)<<setw(8)<<wDeck[i].suit<<((i+1) % 2 ? '\t' : '\n');Top
60 楼seann_liu()回复于 2005-07-14 21:16:50 得分 1
这次应该好啦,哈哈^_^Top
61 楼Atramentous_boy(黑色男孩)回复于 2005-07-14 21:37:07 得分 1
这个程序不是很难,在电子工业出的《C++大学教程》是例题!呵呵~
主要是用来实验随机数的!Top
62 楼fangrk(加把油,伙计!)回复于 2005-07-14 22:09:44 得分 10
以前写过,现在找不到了。
int array[N];//48张牌按照一定的顺序存放
...
for(int i=0;i<N;++i){
int k=[0,N)之间的一个随机数;
if(k!=N-i-1) 交换array[i]和array[k];
}
输出array
或者
int array[N];//48张牌按照一定的顺序存放
...
random_shuffle(array,array+N);//可以查看STL用法Top
63 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-14 22:40:25 得分 0
楼上的,不准使用STL
不过你前面给的效果不错!Top
64 楼fangrk(加把油,伙计!)回复于 2005-07-15 08:58:21 得分 5
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
const char* Num="2 3 4 5 6 7 8 9 10J Q K A ";
const char* Color="SHDC";//四种花色
const int N=13,C=4;
int Array[N*C];
int f=0;
for(int i=0;i<N;++i){
for(int j=0;j<C;++j){
Array[f++]=(i<<2)+j;
}
}
cout<<"牌号\t花色\n";
time_t t;
srand((unsigned) time(&t));
while(--f>=0){
int index=rand()%(f+1);
int Nindex=Array[index]>>2,Cindex=Array[index]&3;
cout<<Num[Nindex*2]<<Num[Nindex*2+1]<<'\t'<<Color[Cindex]<<'\n';
if(index!=f){
int t=Array[index];
Array[index]=Array[f];
Array[f]=t;
}
}
system("pause");
}
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
const char* Num="2 3 4 5 6 7 8 9 10J Q K A ";
const char* Color="SHDC";
const int N=13,C=4;
int Array[N*C];
int f=0;
for(int i=0;i<N;++i){
for(int j=0;j<C;++j){
Array[f++]=(i<<2)+j;
}
}
cout<<"牌号\t花色\n";
time_t t;
srand((unsigned) time(&t));
random_shuffle(Array,Array+f);
while(--f>=0){
int Nindex=Array[f]>>2,Cindex=Array[f]&3;
cout<<Num[Nindex*2]<<Num[Nindex*2+1]<<'\t'<<Color[Cindex]<<'\n';
}
system("pause");
}Top
65 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-15 09:11:07 得分 0
好了,开始结贴Top
66 楼K()回复于 2005-07-15 09:12:03 得分 1
xuexiTop
67 楼sinall()回复于 2005-07-15 09:19:24 得分 1
回复人: iamltd(妖) ( ) 信誉:100 2005-7-14 11:15:07 得分: 0
生成随机数那里是需要技巧的
循环改成:
i=N-1;
do{
t=(rand() % i--);c=0;
do{
if(cards[c] !=CARD_USED)c++;
}while(c<t)
cards[c] = CARD_USED;
out[i]=t;
}while(i>=0)
这样处理以后,每次生成的随机数不再是牌的序号,而是未发的牌的序号。可以保证不会产生冲突。
理论上的时间效率很低,实际运行中应该是最优时间算法了。
--------------------------------------------
语法上大概没错吧。呵呵,我一向记不清语法的。
—————————————————————————————————————————————
可以考虑,第一次抽的牌和第52张交换
第二次抽的牌和第51张交换
……
那么上面的算法应该可以保证了。
Top
68 楼psc88()回复于 2005-07-15 09:19:43 得分 1
学习啊!!!!!!Top
69 楼CSDNWW(中国软件WW)回复于 2005-07-15 17:16:31 得分 1
**************
int i = 0, j = 0, k = 0;
CreatePK( PKD[0] );
for ( ; i < 51; i++ )
{
AddPK( PKD[i] );
}
********
楼主这段代码明显有问题了, 创建从PKD[0]开始, 添加又是从PKD[0]开始Top
70 楼CSDNWW(中国软件WW)回复于 2005-07-15 17:40:57 得分 1
srand( (unsigned)time( NULL ) );
这句这么重要的不能省Top
71 楼CSDNWW(中国软件WW)回复于 2005-07-15 17:53:11 得分 1
**********************
char* FindPK( int i )
{
while( i > 0 )
{
--i;
ptr = ptr->next;
}
********************
即然是循环链表, 为了移够i位而移, 蛮搞笑的Top
72 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-15 20:57:12 得分 0
楼上的,怎么搞笑了?Top




