You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中实现5张牌的反向Fisher–Yates洗牌算法

Fisher-Yates洗牌局部实现问题

需求说明

以整副52张牌为随机池,仅对前5张牌执行洗牌操作,开发时参考现代Fisher-Yates洗牌算法的实现逻辑,原实现存在逻辑问题。

参考算法伪代码

-- 打乱含n个元素的数组a(下标范围0..n-1):
for i from 0 to n−2 do
     j ← 满足 i ≤ j < n 的随机整数
     交换 a[i] 和 a[j]

原实现代码

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>

enum { NUM_CARDS_IN_DECK = 52 };
enum { NUM_CARDS_IN_HAND = 5 };

typedef unsigned int Card;

typedef struct
{
    Card cards[NUM_CARDS_IN_DECK];
} Deck;

unsigned int GetRandomNumber(unsigned int range)
{
    if (range == 0) return UINT_MAX;

    /* 用除法截断找到可被range整除的最大数 */
    const unsigned int randLimit = (RAND_MAX / range) * range;
    unsigned int number = randLimit;
    while (number >= randLimit) number = (unsigned int)rand();
    return number % range;
}

void ShuffleDeck(Deck deck[])
{
    for (unsigned int cardIndex = 0; cardIndex < NUM_CARDS_IN_HAND; cardIndex++)
    {
        unsigned int random = cardIndex + GetRandomNumber(NUM_CARDS_IN_DECK - cardIndex); // 需要random大于等于cardIndex
        printf("\n %d \n", random);
        const Card temp = deck->cards[random];
        deck->cards[random] = deck->cards[cardIndex];
        deck->cards[cardIndex] = temp;
    }
}

int main(void) 
{
    Card cards[NUM_CARDS_IN_DECK] = { 0 };
    Deck deck = { cards };

    for (int index = 0; index < 5; index++) 
    {
        for (int index = 0; index < NUM_CARDS_IN_DECK; index++)
        {
            deck.cards[index] = index;
        }

        printf("\nstarting deck : ");
        for (int index = 0; index < NUM_CARDS_IN_DECK; index++)
        {
            if (index != 0) printf(" ,");
            printf("%d", deck.cards[index]);
        }
        printf("\n");

        ShuffleDeck(&deck);

        printf("\nshuffled deck : ");
        for (int index = 0; index < NUM_CARDS_IN_DECK; index++)
        {
            if (index != 0) printf(" ,");
            printf("%d", deck.cards[index]);
        }
        printf("\n");
    }
}

修复方案

无需在ShuffleDeck()中添加额外循环,直接使用random = cardIndex + GetRandomNumber(NUM_CARDS_IN_DECK - cardIndex)执行无条件交换即可,该方案已验证可正常工作。

内容的提问来源于stack exchange,提问作者Andrew Hanson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:54:05