| 题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
bool
IsContinuous(
int
*numbers ,
int
length)
{
if
(numbers == NULL || length < 1)
return
false
;
qsort
(numbers , length ,
sizeof
(
int
) , compare);
int
numberOfZero = 0;
int
numberOfGap = 0;
//统计数组中0的个数
for
(
int
i = 0 ; i < length && numbers[i] == 0 ; ++i)
++numberOfZero;
//统计数组中的间隔数目
int
small = numberOfZero;
int
big = small + 1;
while
(big < length)
{
//两个数相等,有对子,不可能是顺子
if
(numbers[small] == numbers[big])
return
false
;
numberOfGap += numbers[big] - numbers[small] - 1;
small = big;
++big;
}
return
(numberOfGap > numberOfZero) ?
false
:
true
;
}
int
compare(
const
void
*arg1 ,
const
void
*arg2)
{
return
*(
int
*)arg1 - *(
int
*)arg2;
//升序排序
}
|
qsort函数的用法见qsort(),sort()排序函数。
测试代码: