扑克牌的顺子

题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这五张牌是不是连续的.2~10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以为任意数字.
  我们需要把扑克牌的背景抽象成计算机语言。不难想象,我们可以把5张牌看成由5个数字组成的数组。大小王是特殊的数字,我们不妨把他们都定义为0,这样就能和其他牌区分开来了。
  接下来我们分析怎样判断5个数字是不是连续的,最直观的方法是把数组排序.值得注意的是,由于0可以当成任意数字,我们可以用0去补满数组中的空缺.如果排序之后的数组是不连续的,即相邻的两个数字相隔若干个数字,但只要我们有足够的0可以填满这两个数字的空缺,这个数组实际上还是连续的。举个例子,数组排序之后为{0,1,3,4,5},在1和3之间空缺了一个2,刚好我们有一个0,也就是我们可以把它当成2去填补这个空缺。
 于是我们需要做3件事情:首先把数组排序,再统计数组中0的个数,最后统计排序之后的数组中相邻数字之间的空缺总数。如果空缺总数小于或者等于0的个数,那么这个数组就是连续的;反之则不连续.
  最后,我们还需要注意一点:如果数组中的非0数字重复出现,则该数组不是连续的.换成扑克牌的描述方式就是如果一幅牌里含有对子,则不可能是顺子.
 基于这个思路,我们可以写出如下代码:
  
 1 bool IsContinous(int* numbers,int length)
 2  {
 3   if(numbers==NULL||length<1)
 4   return false;
 5   qsort(numbers,length,sizeof(int),compare);
 6   int numberOfZero=0;
 7   int numberOfGap=0;
 8   
 9   //统计数组中0的个数
10   for(int i=0;i<length&&numbers[i]==0;++i)
11   ++numberOfZero;
12   
13   //统计数组中的间隔数目
14   int small=numberOfZero;
15   int big=small+1;
16   while(big<length)
17   {
18    //如果两个数相等,有对子,不可能是顺子
19    if(numbers[small]==numbers[big])
20     return false;
21    
22    numberOfGap +=number[big]-number[small]-1;
23    small=big;
24     ++big;
25   }
26   return (numberOfGap>numberOfZero) ? false : true;
27 }
28 
29 int compare(const void *arg1,const void * arg2)
30 {
31  return *(int*)arg1 - *(int*)arg2;
32 }
33 

 

posted on 2016-06-06 21:05  wxdjss  阅读(813)  评论(0编辑  收藏  举报

导航