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

PHP Zend实现Secret Santa脚本奇数用户数出现重复条目的问题

问题成因

核心问题出在递归逻辑的执行流程设计缺陷:

  • PHP数组为值传递,每一层generateUsers函数的$users变量都是独立副本,内层对$users的修改不会影响上层函数的$users值
  • 原代码在递归调用语句后没有加终止逻辑,内层递归处理完剩余用户返回后,当前层函数还会继续执行后续的count($users) === 1判断
  • 当总用户数为奇数时,最后几次递归的上层函数的$users副本在执行完配对、unset操作后,正好也只剩1个元素,就会重复触发插入「No Pair」记录的逻辑;偶数场景下所有层递归的$users最后都会被清空为0个,不会触发这个判断因此运行正常。
修复方案

只需要在递归调用语句后直接返回,避免当前层继续执行后续的多余判断即可,同时可移除冗余的matchedUsers相关逻辑,优化后代码示例:

class Match
{
    protected $startingUsers = [
        "User1",
        "User2",
        "User3",
        "User4",
        "User5",                
    ];

    protected $pairs = [];

    function getPairs(): array
    {
        if ($this->generateUsers($this->startingUsers)) {
            return $this->pairs;
        }
        return [];
    }        
    
    function generateUsers(array $defaultUsers, array $updatedUsers = []): bool
    {
        $users = (!empty($updatedUsers)) ? $updatedUsers : $defaultUsers;

        if (count($users) > 1) {
            $randomUserIndex = rand(1, count($users) - 1);
            $this->pairs[] = [$users[0], $users[$randomUserIndex]];
            unset($users[$randomUserIndex]);
            unset($users[0]);

            $newUsers = array_values($users);
            // 递归处理剩余用户后直接返回,不执行后续判断
            return $this->generateUsers($this->startingUsers, $newUsers);
        }

        if (count($users) === 1) {
            $orderedUsers = array_values($users);
            $this->pairs[] = [$orderedUsers[0], "No Pair"];
        }

        return true;
    }
}

$match = new Match();
foreach ($match->getPairs() as $pair) {
    echo "$pair[0] gets $pair[1]";
    echo "\n";
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:57:02