CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C++ 语言

来者有分,今天的一道面试题

楼主jiajun2001(Jagen(嘉俊))2005-07-13 21:03:52 在 C/C++ / C++ 语言 提问

今天面试,一道程序设计题,实现发牌算法。一共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];  
   
  //&frac12;&laquo;start+1&micro;&frac12;end&micro;&Auml;&Aring;&AElig;&Iuml;ò&Ccedil;°&Ograve;&AElig;&para;&macr;&Ograve;&raquo;&Icirc;&raquo;  
  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]&Ouml;&ETH;--->0-12   &Ecirc;&Ccedil;&micro;&Uacute;&Ograve;&raquo;&cedil;&ouml;&Egrave;&Euml;   13-25&Ecirc;&Ccedil;&micro;&Uacute;&para;&thorn;&cedil;&ouml;&Egrave;&Euml;     26   -   38&Ecirc;&Ccedil;&micro;&Uacute;&Egrave;&yacute;&cedil;&ouml;&Egrave;&Euml;       39   -   51   &Ecirc;&Ccedil;&micro;&Uacute;&Euml;&Auml;&cedil;&ouml;&Egrave;&Euml;&micro;&Auml;   &Aring;&AElig;    
  {  
  int       i=0;  
  int       rand=0;  
  int       pokernum   =   52;  
  int       index   =0;  
  int       Tpoker[52];  
   
  //&frac12;&laquo;52&Otilde;&Aring;&Aring;&AElig;·&Aring;&Egrave;&euml;&Ecirc;&yacute;×éTpoker&Ouml;&ETH;,·&cent;&Aring;&AElig;&micro;&Auml;&Ecirc;±&ordm;ò&acute;&Oacute;&Ouml;&ETH;&Egrave;&iexcl;&sup3;&ouml;    
  for(i=0;i<pokernum;i++)  
  {  
  Tpoker[i]   =   i;  
  }  
   
  //start   to   ·&cent;&Aring;&AElig;  
  index   =0;  
  while(pokernum){  
  rand   =   rand();  
  rand   %=   pokernum;       //&Ocirc;&Uacute;0&micro;&frac12;pokernum-1&sup2;ú&Eacute;ú&Ograve;&raquo;&cedil;&ouml;&Euml;&aelig;&raquo;ú&Ecirc;&yacute;  
   
  Poker[index++]   =   Tpoker[rand];     //&Egrave;&iexcl;&sup3;&ouml;&Ocirc;&Uacute;&acute;&Euml;&acute;&brvbar;&micro;&Auml;&Ecirc;&yacute;×&Ouml;  
   
  //rand&Icirc;&raquo;&Ouml;&Atilde;&micro;&Auml;&Aring;&AElig;&Ograve;&Ntilde;&frac34;&shy;&Egrave;&iexcl;&sup3;&ouml;,&frac12;&laquo;rand+1&micro;&frac12;pokernum-1&Iuml;ò&Ccedil;°&Ograve;&AElig;&Ograve;&raquo;&Icirc;&raquo;  
  movepoker(Tpoker,rand,pokernum-1);  
  //&Ecirc;&pound;&Oacute;à&micro;&Auml;&Aring;&AElig;&Ecirc;&yacute;&frac14;&otilde;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

相关问题

  • 一道面试题
  • 一道面试题????
  • MICROSOFT 面试题一道
  • 一道面试题
  • 一道面试题!
  • 一道面试题
  • 一道面试题
  • 一道面试题
  • 一道面试题
  • 一道面试题

关键词

  • 算法
  • 指针
  • 黑桃
  • 红桃
  • 方块
  • 梅花
  • pk
  • card
  • oee
  • 赋值

得分解答快速导航

  • 帖主:jiajun2001
  • qfeng_zhao
  • durkingzhang
  • AntonlioX
  • chengjr
  • yangbc
  • god_sun
  • WecanHuang
  • K
  • boxban
  • vsfan
  • MagicCarmack
  • wiali
  • wiali
  • mayingbao
  • sea2000cn
  • aayy
  • sy_lyx
  • lonelyforest
  • boxban
  • login__whf
  • xuanwenchao
  • syg1
  • junnyfeng
  • junnyfeng
  • iamltd
  • boyu_song
  • simec
  • yvhkdragon
  • netfloator
  • qingyuan18
  • sinall
  • boxban
  • OMA_yudy
  • hewittlee
  • seann_liu
  • seann_liu
  • foochow
  • seann_liu
  • tslkfyh
  • seann_liu
  • yangwuhan
  • jiangbo1125
  • seann_liu
  • seann_liu
  • seann_liu
  • Atramentous_boy
  • fangrk
  • fangrk
  • K
  • sinall
  • psc88
  • CSDNWW
  • CSDNWW
  • CSDNWW

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo