面试题36:扑克牌中的顺子

1.题目描述

题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。

2.题目分析

我们需要把扑克牌的背景抽象成计算机语言。不难想象,我们可以把5张牌看成由5个数字组成的数组。大、小王是特殊的数字,我们不妨把它们都定义为0,这样就能和其他扑克牌区分开来了,接下来我们分析怎样判断5个数字是不是连续的,最直观的方法是把数组排序。值得注意的是,由于0可以当成任意数字,我们可以用0去补满数组中的空缺。如果排序之后的数组不是连续的,即相邻的两个数字相隔若干个数字,那么只要我们有足够的0可以补满这两个数字的空缺,这个数组实际上还是连续的。

举个例子,数组排序之后为{0,1,3,4,5},在1和3之间空缺了一个2,刚好我们有一个0,也就是我们可以把它当成2去填补这个空缺。

于是我们需要做3件事情

  1. 首先把数组排序;其次统计数组中0的个数
  2. 最后统计排序之后的数组中相邻数字之间的空缺总数
  3. 如果空缺的总数小于或者等于0的个数,那么这个数组就是连续的:反之则不连续。

最后我们还需要注意一点:如果数组中的非0数字重复出现,则该数组不是连续的。换成扑克牌的描述方式就是:如果一副牌里含有对子,则不可能是顺子。

3.code

#include <cstdio>
#include <cstdlib>int Compare(const void *arg1, const void *arg2);bool IsContinuous(int* numbers, int length)
{if(numbers == nullptr || 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;
}// ====================测试代码====================
void Test(const char* testName, int* numbers, int length, bool expected)
{if(testName != nullptr)printf("%s begins: ", testName);if(IsContinuous(numbers, length) == expected)printf("Passed.\n");elseprintf("Failed.\n");
}void Test1()
{int numbers[] = { 1, 3, 2, 5, 4 };Test("Test1", numbers, sizeof(numbers) / sizeof(int), true);
}void Test2()
{int numbers[] = { 1, 3, 2, 6, 4 };Test("Test2", numbers, sizeof(numbers) / sizeof(int), false);
}void Test3()
{int numbers[] = { 0, 3, 2, 6, 4 };Test("Test3", numbers, sizeof(numbers) / sizeof(int), true);
}void Test4()
{int numbers[] = { 0, 3, 1, 6, 4 };Test("Test4", numbers, sizeof(numbers) / sizeof(int), false);
}void Test5()
{int numbers[] = { 1, 3, 0, 5, 0 };Test("Test5", numbers, sizeof(numbers) / sizeof(int), true);
}void Test6()
{int numbers[] = { 1, 3, 0, 7, 0 };Test("Test6", numbers, sizeof(numbers) / sizeof(int), false);
}void Test7()
{int numbers[] = { 1, 0, 0, 5, 0 };Test("Test7", numbers, sizeof(numbers) / sizeof(int), true);
}void Test8()
{int numbers[] = { 1, 0, 0, 7, 0 };Test("Test8", numbers, sizeof(numbers) / sizeof(int), false);
}void Test9()
{int numbers[] = { 3, 0, 0, 0, 0 };Test("Test9", numbers, sizeof(numbers) / sizeof(int), true);
}void Test10()
{int numbers[] = { 0, 0, 0, 0, 0 };Test("Test10", numbers, sizeof(numbers) / sizeof(int), true);
}// 有对子
void Test11()
{int numbers[] = { 1, 0, 0, 1, 0 };Test("Test11", numbers, sizeof(numbers) / sizeof(int), false);
}// 鲁棒性测试
void Test12()
{Test("Test12", nullptr, 0, false);
}int main(int argc, char* argv[])
{Test1();Test2();Test3();Test4();Test5();Test6();Test7();Test8();Test9();Test10();Test11();Test12();return 0;
}

4.拓展-关于qsort函数

std::qsort
定义于头文件 <cstdlib>void qsort( void *ptr, std::size_t count, std::size_t size, /*compare-pred*/* comp );以升序排序 ptr 所指向的给定数组。数组含 count 个 size 字节大小的元素。用 comp 所指向的函数比较对象。若 comp 指示二个元素等价,则其顺序未指定。参数
ptr     -   指向要排序的数组的指针
count   -   数组元素数
size    -   数组中元素的大小,以字节表示
comp    -   比较函数。若首个参数小于第二个,则返回负整数值,若首个参数大于第二个,则返回正整数值,若两参数等价,则返回零。比较函数的签名应等价于如下形式:int cmp(const void *a, const void *b);该函数必须不修改传递给它的对象,而且在调用比较相同对象时必须返回一致的结果,无关乎它们在数组中的位置。返回值
(无)

扑克牌中的顺子。从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看成任意数字。相关推荐

  1. C#:今日上机问题描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。

    using System; //写的不太严格,直接用14张牌来抽了,1-13,大小王为0,没有判断相同的不能超过4张,为0的相同不能超过两张. namespace _201919144122WeiXu ...

  2. 剑指Offer题目:从扑克牌中随机抽 5 张牌,判断是不是顺子,即这 5 张牌是不是连续的。 2-10 为数字本身,A 为 1,J 为 11,Q 为 12,K 为 13,而大小王可以看成任意的 数字。

    剑指Offer面试题 44:扑克牌的顺子 从扑克牌中随机抽 5 张牌,判断是不是顺子,即这 5 张牌是不是连续的. 2-10 为数字本身,A 为 1,J 为 11,Q 为 12,K 为 13,而大小王 ...

  3. php 判断5张牌是不是顺子,从扑克牌中随机抽取5张牌,判断是不是一个顺子,即这5张牌是不是连续(面试题)...

    从扑克牌中随机抽取5张牌,判断是不是一个顺子,即这5张牌是不是连续的2-10位数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字 统计数组中出现的次数,判断等于0,大于1大于2大 ...

  4. 【转】判断五张牌是不是一个顺子

    转自:http://hi.baidu.com/erennetwork/blog/item/f2942435d834e650ad4b5f8a.html 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5 ...

  5. java打印扑克牌_JAVA入门第三季-简易扑克牌程序-个人编写-源代码(含截图)

    整体思路 创建Card类,定义单张扑克的属性(点数,花色),行为(比较大小),以及比较大小的规则: 创建Poker类,定义一副扑克牌,采用List集合框架: 创建Player类,定义玩家属性(id,名 ...

  6. verilog中数组的定义_systemverilog中的数组操作

    sv中的数组基本操作:/* Exercsise platform :     Questa Sim 10.1b */ class Array; int array[9:0] ; function ne ...

  7. WPF中使用WindowChrome自定义窗口中遇到的最大化问题

    FrameWork 4.5 之后,内置了WindowChrome类,官方文档: https://msdn.microsoft.com/en-us/library/system.windows.shel ...

  8. java中的异常处理语句_Java中实现异常处理的基础知识

    Java中实现异常处理的基础知识 异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象. 例如:数组越界和被0除. ...

  9. java输出一副扑克牌_JAVA编一副扑克牌

    匿名用户 7级 2011-05-03 回答 public static void main(String [] args){ List li = new ArrayList(); List li2 = ...

最新文章

  1. 2018.3.15校内互测总结-点分治-线段树
  2. SpringBoot 实战 (八) | 使用 Spring Data JPA 访问 Mysql 数据库
  3. shell脚本——系统变量 与 变量(定义 使用 只读 删除)
  4. 组件通信 eventtBus
  5. 我学习Python的三个神级网站
  6. SAP Fiori Elements遇到问题时,该如何调试?
  7. supervisor开机自启动方法
  8. 在linux中dns不安装coching,ubuntu 8.04下openldap的安装和使用
  9. mysql5.6 pt-query-digest_pt-query-digest安装及分析
  10. 实战Python:详解利用Python和Pygame实现飞机大战
  11. Atitit.判断汉字的编码 regedit 注册表里面的reg_sz
  12. 操作系统 | Linux基础教程
  13. 路漫漫其修远兮,吾将上下而求索
  14. sox处理mp3_sox 转码 amr转MP3
  15. 0068 terra vista 4.0安装包及破解教程
  16. 绝对干货3000字,手把手带你用Python实现一个量化炒股策略,小白也能看得懂!...
  17. 用python 画一个美国队长盾牌
  18. c语言求解连续数列编程题,数列-题解(C语言代码)
  19. 无领导小组讨论(一)
  20. 662k稳压芯片电路图,线性稳压芯片

热门文章

  1. LeetCode:167. 两数之和 II - 输入有序数组(java)
  2. 分省/市政府性债务数据财政收支数据财政透明度
  3. mysql自定义函数-随机生成人员姓名
  4. 4.第K个数(快速选择排序)
  5. tomcat布置前端项目
  6. 保障4-0601任务打卡
  7. nodejs优雅的使用es6语法
  8. element ui input限制输入6位数字(短信验证码)
  9. MySQL数据库(操作命令)
  10. Vue-Router前端路由的两种模式、区别、原理?