自学内容网 自学内容网

华为OD机试真题-斗地主之顺子

题目描述:
在斗地主只扑克牌游戏中,扑克牌由小到大的顺序为:3,4,5,6,7,8,9,10,J,Q,K,A,2,玩家可以出的扑克牌阵型有:单,张、对子、顺子、飞机、炸弹等。其中顺子的出牌规则为:由至少5张由小到大连续递增的扑克牌只组成,且不能包含2。
**例如**:(3.4,5,6,7}、(3,4,5,6,7,8,9,10,J,Q,K,A}都是有效的顺子;
**而**{Q,K,A,2}、(2,3,4,5,6}、(3,4,5,6}、(3,4,5,6,8)等都不是顺子。
给定一个包含13张牌的数组,如果有满足出牌规则的顺子,请输出顺子。
如果存在多个顺子,请每行输出一个顺子,且需要按顺子的第一张牌的大小(必须从小到大)依次输出。
如果没有满足出牌规则的顺子,请输出NO。输入描述:13张任意顺序的扑克牌,每张扑克牌数字用空格隔开,每张扑克牌的数字都是合法的,并且不包括大小王:2 9 J 2 3 4 K A 7 9 A 5 6不需要考虑输入为异常字符的情况。

输出描述:
组成的顺子,每张扑克牌数字用空格隔开:3 4 5 6 7

**示例1:**
输入:2 9 J 2 3 4 K A 7 9 A 5 6
输出:3 4 5 6 7

public class PokerGame {
    private static final Logger log = LoggerFactory.getLogger(PokerGame.class);

    /**
     * 查找并打印给定扑克牌序列中的所有有效顺子
     * 顺子定义为连续的五张牌序列
     * 
     * @param cards 以空格分隔的牌值字符串,每张牌用2位数字表示,如"03 04 05 06 07 08 09 10 11 12 01 02 01"
     *               其中01代表A,11代表J,12代表Q,13代表K
     */
    public static void findValidSequences(String cards) {
        // 检查输入是否有效
        if (cards == null || cards.isEmpty()) {
            System.out.println("Invalid input.");
            return;
        }
        log.info("Input: {}", cards);
    
        // 将输入的字符串转换为整数数组并排序
        int[] cardValues = new int[13];
        String[] splitCards = cards.split(" ");
        if (splitCards.length != 13) {
            System.out.println("Invalid number of cards.");
            return;
        }
        // 遍历splitCards数组,将每个元素转换为对应的牌值,并存储在cardValues数组中
        for (int i = 0; i < splitCards.length; i++) {
            cardValues[i] = parseCardValue(splitCards[i]);
        }
        //排序
        Arrays.sort(cardValues);
    
        // 查找并输出所有有效的顺子
        List<List<Integer>> sequences = findSequences(cardValues);
        if (sequences.isEmpty()) {
            System.out.println("NO");
        } else {
            sequences.forEach(PokerGame::printSequence);
        }
    }

    private static int parseCardValue(String cardStr) {
        switch (cardStr) {
            case "2": return 2;
            case "3": return 3;
            case "4": return 4;
            case "5": return 5;
            case "6": return 6;
            case "7": return 7;
            case "8": return 8;
            case "9": return 9;
            case "10": return 10;
            case "J": return 11;
            case "Q": return 12;
            case "K": return 13;
            case "A": return 14;
            default: throw new IllegalArgumentException("Invalid card: " + cardStr);
        }
    }

    private static List<List<Integer>> findSequences(int[] sortedCards) {
        List<List<Integer>> sequences = new ArrayList<>();
        // 从第0张牌开始,遍历所有可能的顺子
        for (int i = 0; i <= sortedCards.length - 5; i++) {
            // 检查当前位置是否为有效顺子
            if (isSequence(sortedCards, i)) {
                List<Integer> sequence = new ArrayList<>();
                // 将当前顺子添加到结果列表中
                for (int j = i; j < i + 5; j++) {
                    sequence.add(sortedCards[j]);
                }
                sequences.add(sequence);
               // 跳过已使用的四张牌,只需移动到下一个待检查的起始位置
            }
        }
        return sequences;
    }

    private static boolean isSequence(int[] cards, int start) {
        int gap = 0; // 用于记录非顺序牌之间的差值
        // 检查起始位置是否为2,如果是,则不是有效顺子
        if (cards[start] == 2) {
            return false;
        }
        // 遍历5张牌,检查是否为顺子
        for (int i = start; i < start + 5; i++) {
            // 检查是否出现重复牌
            if (i > start && cards[i] == cards[i - 1]) {
                // 重复牌,不是有效顺子
                return false;
            }
            // 检查是否出现A和2之间的间隔
            if (cards[i] == 14 && i + 1 < start + 5 && cards[i + 1] == 2) {
                // A可以视为序列的开始,但与下一张牌之间的间隔必须为3(14-1=13, 13-10=3)
                gap = 3;
            } else if (cards[i] == 2 && i > start && cards[i - 1] == 14) {
                // 前面是A,这里是2,忽略前面的gap检查
                gap = 0;
            } else if (i > start) {
                // 检查间隙是否为1(除了A后面紧跟2的情况)
                if (cards[i] - cards[i - 1] != 1 + gap) {
                    return false;
                }
                gap = 0; // 重置gap
            }
        }
        return true;
    }

    private static void printSequence(List<Integer> sequence) {
        // 将整数列表转换为字符串并输出
        System.out.println(sequence.stream().map(PokerGame::convertValueToString).collect(Collectors.joining(" ")));
    }

    private static String convertValueToString(int value) {
        switch (value) {
            case 2: return "2";
            case 3: return "3";
            case 4: return "4";
            case 5: return "5";
            case 6: return "6";
            case 7: return "7";
            case 8: return "8";
            case 9: return "9";
            case 10: return "10";
            case 11: return "J";
            case 12: return "Q";
            case 13: return "K";
            case 14: return "A";
            default: throw new IllegalArgumentException("Invalid value: " + value);
        }
    }


    public static void main(String[] args) {
        String input = "2 9 J 2 3 4 K A 7 8 A 5 6";
        findValidSequences(input);
    }

原文地址:https://blog.csdn.net/lbp0123456/article/details/142481289

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!