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

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

算法分析:
我们需要把扑克牌的背景抽象成计算机语言。不难想象,我们可以把五张牌看成由五个数字组成的数组。大小王是特殊的数字,我们不妨把他们定义为0,这样就能和其他牌区分开来了。
接下来我们分析判断5个数字是不是连续的,最直观的方法是把数组排序。值得注意的是,由于0可以当成任意的数字,我们可以用0去补满数组中的空缺。如果排序之后的数组不是连续的,即相邻的两个数字像个若干个数字,但只要我们有足够的0可以补满这两个空缺的数字,这个数组实际上还是连续的。举个例子,数组排序之后为{0,1,3,4,5},在1和3之间空缺一个2,刚好我们有一个0,也就是我们可以把它当成2去填补这个空缺。
于是我们需要做3件事:首先把数组排序,再统计数组中0的个数,最后统计排序之后数组中相邻的数字之间的空缺总数。如果空缺综述小于或者等于0的个数,那么这个数组就是连续的;反之则不连续。
最后我们还需要注意一点:如果数组中的非0数字反复出现,则该数组不是连续的。换成扑克牌的描述方式就是如果一副牌里含有对子,则不可能是顺子。

算法源程序:
[java]  view plain  copy
  1. /**************************************************************       
  2. * Copyright (c) 2016,  
  3. * All rights reserved.                    
  4. * 版 本 号:v1.0                    
  5. * 题目描述:扑克牌的顺子 
  6. *            从扑克牌中随机抽出5张牌,判断是不是一个顺子,即这五张牌是不是连续的。2——10为数字本身, 
  7. *           A为1,J为11,Q为12,K为13,而大小王为任意数字。 
  8. * 输入描述:请输入五张牌: 
  9. *           0 0 3 4 7 
  10. * 程序输出: 这是一张顺子扑克牌 
  11. * 问题分析: 无 
  12. * 算法描述: 于是我们需要做3件事:首先把数组排序,再统计数组中0的个数,最后统计排序之后数组中相邻的数字之间的空缺总数。 
  13. *           如果空缺综述小于或者等于0的个数,那么这个数组就是连续的;反之则不连续。 
  14. * 完成日期:2016-09-27 
  15. ***************************************************************/  
  16. package org.marsguo.offerproject44;  
  17.   
  18. import java.util.Scanner;  
  19.   
  20. class SolutionMethod1{  
  21.       
  22. public void sortfun(int[] arrays,int start, int end){  
  23.         int numOfZero=0;  
  24.         if(start>=end){                              //判断数组的起始和终止是否相同,相同表示已经都全部排完,返回  
  25.             return;  
  26.         }  
  27.         int i = start;                              //i指向数组的起始位  
  28.         int j = end;                                //j指向数组的末位  
  29.         int key = arrays[i];                        //选取数组的第一位为关键字key,基准元素  
  30.         boolean flag = true;                        //设置标志位,用于判断是i++还是j--;这个很重要  
  31.         while(i != j){                              //如果i≠j,表示还没有比较完,即即关键字左右两侧还不是最小与最大  
  32.             if(flag){                     
  33.                 if(key>arrays[j]){                   //从后向前遍历,找到小于key的值,  
  34.                     swap(arrays,i,j);               //找到小于key的值后将arrays[i]与此值交换  
  35.                     flag = false;  
  36.                 }else{                              //如果没有找到的话j--,向前遍历  
  37.                     j--;  
  38.                 }  
  39.             }else{                                
  40.                 if(key<arrays[i]){                   //从前向后遍历,找到大于key的值  
  41.                     swap(arrays,i,j);               //将此值与arrays[j]进行交换  
  42.                     flag = true;  
  43.                 }else{                              //如果没有找到话就将i++,向后遍历  
  44.                     i++;  
  45.                 }  
  46.             }  
  47.         }  
  48.         //sprint(arrays);                               //打印每次排序后的数组  
  49.         sortfun(arrays,start,j-1);                  //递归调用,将基准元素的前半段数组再用此方法进行排序,直到所有都排完为止。  
  50.         sortfun(arrays,i+1,end);                    //递归调用,将基准元素的后半段数组再用此方法进行排序,直到所有都排完为止。  
  51.           
  52.         //System.out.println("排序后的数组是:");  
  53.         for(int k = 0; k < arrays.length; k++){  
  54.             if(arrays[k] == 0){  
  55.                 numOfZero++;  
  56.             }  
  57.             //System.out.print("numOfZero= " + numOfZero + ";"+arrays[k] + ", ");  
  58.             //System.out.print(arrays[k] + ", ");  
  59.         }  
  60.           
  61.         IsContinuousFun(arrays, numOfZero);  
  62.     }  
  63.     public void swap(int[] array,int i,int j){            
  64.         int temp;  
  65.         temp = array[i];  
  66.         array[i] = array[j];  
  67.         array[j] = temp;  
  68.     }  
  69.       
  70.     public void IsContinuousFun(int[] array,int numOfZero){  
  71.         int numOfGap = 0;               //判断数字中间空了多少个0  
  72.         //System.out.println("numberOfZero = " + numOfZero);  
  73.         for(int j = 1; j < array.length; j++){  
  74.             int flag = array[j] - array[j-1];       //用排序数组中后一个数字-前一个数字  
  75.             if(array[j] == array[j-1] && array[j] != 0){        //如果数组中有重复的非0数字,则不是顺子,退出  
  76.                 System.out.println("有重复数字,不是顺子牌");  
  77.                 return;  
  78.             }  
  79.             else if(flag != 1 && flag != 0 && array[j-1] != 0){         //判断不是连续的数字,也不是0,  
  80.                 numOfGap += flag-1;                                 //非0数字间缺少的数字的个数  
  81.             }  
  82.         }  
  83.         if(numOfZero != numOfGap){  
  84.             System.out.println("这不是一个顺子扑克牌");  
  85.         }  
  86.         else{  
  87.             System.out.println("这是一张顺子扑克牌");  
  88.         }  
  89.     }  
  90.       
  91.       
  92. }  
  93. public class IsContinuous {  
  94.     public static void main(String[] args){  
  95.         Scanner scanner = new Scanner(System.in);                       //扫描键盘输入  
  96.         System.out.println("请输入五张牌:");  
  97.         String str = scanner.nextLine();                                //将键盘输入转化为字符串  
  98.         String[] temp = str.split(" ");                                 //将字符串用“ ”分开转化为字符串数组  
  99.         scanner.close();  
  100.         int[] array = new int[temp.length];                             //定义一个整型数组array  
  101.         for(int i = 0; i< temp.length; i++){                         //将字符串数组强制转化为整型数组  
  102.             array[i] = Integer.parseInt(temp[i]);                       //这种方法非常巧妙  
  103.         }  
  104.           
  105.         SolutionMethod1 solution1 = new SolutionMethod1();  
  106.         //solution1.quicksort(array, 0, array.length-1);  
  107.         solution1.sortfun(array, 0, array.length-1);  
  108.     }  
  109. }  
### 回答1: 可以按照以下步骤判断是否为顺子: 1. 将抽到的5张牌从小到大排序。 2. 统计大小王的数量,即大小王的个数。 3. 统计相邻两张牌之间的差值,如果差值为0,则说明有对子,不可能为顺子,直接返回false。 4. 如果差值不为0,则将差值累加起来,得到差值的总和。 5. 如果差值总和小于等于大小王的个数,说明可以通过大小王来填补差值,使得可以组成顺子,返回true。 6. 如果差值总和大于大小王的个数,说明无法通过大小王来填补差值,不能组成顺子,返回false。 例如,抽到的5张牌为[3, 5, 6, 7, 8],其大小王的个数为1,那么按照上述步骤进行判断: 1. 排序后为[3, 5, 6, 7, 8]。 2. 大小王的个数为1。 3. 差值分别为[2, 1, 1, 1],没有对子。 4. 差值总和为5。 5. 差值总和小于等于大小王的个数,可以通过大小王来填补差值,可以组成顺子,返回true。 因此,[3, 5, 6, 7, 8]是一个顺子。 ### 回答2: 判断扑克牌顺子需要考虑以下几点: 1. 先将每个点数的分到不同的桶; 2. 从小到大遍历桶,统计0的个数; 3. 统计桶非0元素之间的差值,若差值大于1,则不是顺子; 4. 如果没有非0元素之间的差值大于1,则为顺子;若非0元素有重复的,则不是顺子。 具体实现步骤如下: 1. 定义一个长度为14的桶,桶的下标从1到13表示扑克牌的点数,0表示大小王; 2. 遍历数组,将每个点数的分别存入对应桶; 3. 统计0的个数,并将非0元素存入一个新的数组,并排序; 4. 统计非0元素之间的差值,若差值大于1,则不是顺子; 5. 若非0元素有重复的,则不是顺子; 6. 若满足以上两个条件,则为顺子。 例如,若抽到的5张牌为3、4、5、6、7,其对应桶的情况如下: ``` bucket[3] = 1; bucket[4] = 1; bucket[5] = 1; bucket[6] = 1; bucket[7] = 1; ``` 统计0的个数得到0,将非0元素存入新数组并排序后得到{3, 4, 5, 6, 7},计算其差值为1,故为顺子。 再例如,若抽到的5张牌为3、4、5、5、7,其对应桶的情况如下: ``` bucket[3] = 1; bucket[4] = 1; bucket[5] = 2; bucket[7] = 1; ``` 统计0的个数得到0,将非0元素存入新数组并排序后得到{3, 4, 5, 5, 7},其有重复的5,故不是顺子。 ### 回答3: 扑克牌顺子算法是一种判断抽取的五张是否为顺子的算法。该算法需要首先对于抽取的五张进行排序,然后在排序后的判断是否连续。具体步骤如下: 1. 对抽取的五张进行排序,可以采用任何一种排序算法,比如常用的快速排序、归并排序等。 2. 判断排序后的是否有大小王,如果有则先把它们拿出来。 3. 继续判断,如果排序后的存在相同的,则一定不可能为顺子。 4. 如果排序后的不存在相同的,再判断的最大值与最小值之间的差是否小于等于4,如果是,则这五张可以组成一个顺子;否则不是顺子。 5. 如果有大小王,则可以使用大小王替换的任何一张牌,替换后再进行判断。 以上就是扑克牌顺子算法的具体流程。在实际应用,可以把该算法封装成一个函数,方便调用和复用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值