
本文旨在解决在使用PHP实现Secret Santa(秘密圣诞老人)算法时,当用户数量为奇数时出现的配对问题。通过分析问题代码,找出导致最后一个用户重复配对的原因,并提供修复方案。同时,提出一种更优雅的替代方案,确保所有用户都能参与配对。
原代码在处理奇数数量用户时,由于递归调用generateUsers函数,导致在只剩下一个用户时,会重复执行一次配对逻辑,从而产生“User X gets No Pair”的重复结果。 根本原因在于递归调用后,没有充分判断剩余用户数量,导致单用户情况下的配对逻辑被多次执行。
要解决这个问题,需要在递归调用generateUsers之前,确保剩余用户数量大于1。 修改后的代码如下:
function generateUsers(array $defaultUsers, array $updatedUsers = []): bool
{
$users = (!empty($updatedUsers)) ? $updatedUsers : $defaultUsers;
if (count($users) > 1) {
if ($this->matchedUsers !== count($this->startingUsers)) {
// Pick random user and match with current user. Reset array and repeat until 1 or no users left.
$randomUserIndex = rand(1, count($users) - 1);
$this->pairs[] = [$users[0], $users[$randomUserIndex]];
unset($users[$randomUserIndex]);
unset($users[0]);
// Remove pair from list so they can't be assigned again. Reset array for 0 based index $users[0]
$newUsers = array_values($users);
// Check that there are two or more users
if(count($newUsers) > 1){
$this->generateUsers($this->startingUsers, $newUsers);
}
$this->matchedUsers += 2;
}
}
// If only one user remains can't allocate a Pair
if (count($users) === 1) {
$orderedUsers = array_values($users);
$this->pairs[] = [$orderedUsers[0], "No Pair"];
return true;
}
return true;
}在generateUsers函数中,添加了if(count($newUsers) > 1)判断,确保只有当剩余用户数量大于1时才进行递归调用。 这样可以避免在只剩下一个用户时,重复执行配对逻辑。
立即学习“PHP免费学习笔记(深入)”;
除了上述修复方案外,还可以考虑使用循环配对的方式,确保所有用户都能参与配对,避免出现“No Pair”的情况。 这种方案的核心思想是,将所有用户组成一个环,每个用户都从环中的下一个用户那里收到礼物。
示例代码如下:
class Match
{
protected $startingUsers = [
"User1",
"User2",
"User3",
"User4",
"User5",
];
protected $pairs = [];
function getPairs(): array
{
$users = $this->startingUsers;
$count = count($users);
for ($i = 0; $i < $count; $i++) {
$giver = $users[$i];
$receiverIndex = ($i + 1) % $count; // 确保循环回到第一个用户
$receiver = $users[$receiverIndex];
$this->pairs[] = [$giver, $receiver];
}
return $this->pairs;
}
}
$match = new Match();
foreach ($match->getPairs() as $pair) {
echo "$pair[0] gets $pair[1]";
echo "\n";
}这段代码将用户列表视为一个环,每个用户都会收到来自下一个用户的礼物,最后一个用户则会收到来自第一个用户的礼物。 这样就避免了“No Pair”的情况,确保所有用户都能参与到Secret Santa活动中。
本文分析了在PHP Secret Santa算法中,处理奇数用户数量时可能出现的问题,并提供了两种解决方案:
选择哪种方案取决于具体的需求。 如果需要保留“No Pair”的情况,可以选择第一种方案。 如果希望所有用户都能参与配对,避免出现“No Pair”的情况,可以选择第二种方案。循环配对的方式更加优雅,避免了特殊情况的处理,代码也更简洁易懂。
以上就是PHP Secret Santa 算法:解决奇数用户配对问题的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号