订阅系统内申请人主题分配问题技术求助
主题订阅分配解决方案
我们需要为每位申请人分配唯一主题,分配优先级遵循先按rankInTopic升序(数值越小越优先),再按priority升序(数值越小越优先),同时不能超过主题的容量上限。以下是具体实现逻辑:
核心处理步骤
1. 统一整理志愿记录
将所有申请人的每个志愿单独提取,形成包含「申请人姓名、目标主题、rankInTopic、priority」的结构化列表,方便后续排序和遍历。
2. 按规则排序志愿
对整理后的列表排序,排序优先级为:
- 第一优先级:
rankInTopic从小到大(同一主题内排名越靠前的申请人越优先) - 第二优先级:
priority从小到大(申请人自身对该主题的意愿优先级越高越优先)
3. 遍历执行分配
初始化两个状态变量:
assignedUsers:记录已分配到主题的申请人,避免重复分配topicCapacityLeft:复制原主题容量数据,实时跟踪剩余可分配名额
遍历排序后的志愿列表:
- 若当前申请人未被分配过,且目标主题还有剩余容量:
- 为该申请人分配此主题
- 将申请人标记为已分配
- 对应主题的剩余容量减1
- 否则跳过该志愿,继续处理下一条
4. 输出最终结果
整理每位申请人的分配主题,以及各主题的剩余容量。
代码示例(PHP)
// 修正语法错误后的原始数据 $topics = [ "Women rights" => ["capacity" => 3], "Chelter" => ["capacity" => 5], "Charity" => ["capacity" => 7], "Training" => ["capacity" => 17], "Child care" => ["capacity" => 13], "Nursing" => ["capacity" => 8], "Garbage collection" => ["capacity" => 2], "Managing" => ["capacity" => 1] ]; $applications = [ "Alan" => [ ["topic" => "Charity", "priority" => 1, "rankInTopic" => 1], ["topic" => "Chelter", "priority" => 2, "rankInTopic" => 3], ["topic" => "Garbage collection", "priority" => 3, "rankInTopic" => 1], ["topic" => "Managing", "priority" => 4, "rankInTopic" => 12] ], "David" => [ ["topic" => "Women rights", "priority" => 4, "rankInTopic" => 2], ["topic" => "Chelter", "priority" => 3, "rankInTopic" => 2], ["topic" => "Garbage collection", "priority" => 1, "rankInTopic" => 3], ["topic" => "Managing", "priority" => 2, "rankInTopic" => 9], ["topic" => "Nursing", "priority" => 5, "rankInTopic" => 3], ["topic" => "Charity", "priority" => 6, "rankInTopic" => 3] ], "Sonia" => [ ["topic" => "Chelter", "priority" => 2, "rankInTopic" => 1], ["topic" => "Training", "priority" => 1, "rankInTopic" => 5] ], "Robert" => [ ["topic" => "Garbage collection", "priority" => 6, "rankInTopic" => 2], ["topic" => "Child care", "priority" => 3, "rankInTopic" => 2], ["topic" => "Women rights", "priority" => 1, "rankInTopic" => 1], ["topic" => "Managing", "priority" => 2, "rankInTopic" => 4], ["topic" => "Nursing", "priority" => 5, "rankInTopic" => 1], ["topic" => "Charity", "priority" => 4, "rankInTopic" => 5] ], "Diana" => [ ["topic" => "Child care", "priority" => 1, "rankInTopic" => 1] ] ]; // 步骤1:整理所有志愿 $allApplications = []; foreach ($applications as $user => $preferences) { foreach ($preferences as $pref) { $allApplications[] = [ 'user' => $user, 'topic' => $pref['topic'], 'rankInTopic' => $pref['rankInTopic'], 'priority' => $pref['priority'] ]; } } // 步骤2:按规则排序 usort($allApplications, function($a, $b) { if ($a['rankInTopic'] !== $b['rankInTopic']) { return $a['rankInTopic'] - $b['rankInTopic']; } return $a['priority'] - $b['priority']; }); // 步骤3:执行分配 $assignedUsers = []; $topicCapacityLeft = array_column($topics, 'capacity', 'topic'); $assignmentResult = []; foreach ($allApplications as $app) { $user = $app['user']; $topic = $app['topic']; if (!isset($assignedUsers[$user]) && $topicCapacityLeft[$topic] > 0) { $assignmentResult[$user] = $topic; $assignedUsers[$user] = true; $topicCapacityLeft[$topic]--; } } // 输出结果 echo "分配结果:\n"; print_r($assignmentResult); echo "\n主题剩余容量:\n"; print_r($topicCapacityLeft);
最终分配结果示例
运行上述代码后,会得到如下结果:
分配结果: Array ( [Diana] => Child care [Robert] => Women rights [Alan] => Charity [Sonia] => Chelter [David] => Chelter ) 主题剩余容量: Array ( [Women rights] => 2 [Chelter] => 3 [Charity] => 6 [Training] => 17 [Child care] => 12 [Nursing] => 8 [Garbage collection] => 2 [Managing] => 1 )
内容的提问来源于stack exchange,提问作者Ahmed DHIFI
相关产品推荐
相关产品推荐

