使用PHP读写欧冠赛事结果文件:无法生成正确排名的求助
欧冠G组赛事排名计算问题
赛事数据与规则
赛事结果数据
RB Leipzig;AS Monaco;draw
FC Porto;Besiktas JK;loss
Besiktas JK;RB Leipzig;win
AS Monaco;FC Porto;loss
AS Monaco;Besiktas JK;loss
RB Leipzig;FC Porto;win
Besiktas JK;AS Monaco;draw
FC Porto;RB Leipzig;win
Besiktas JK;FC Porto;draw
AS Monaco;RB Leipzig;loss
FC Porto;AS Monaco;win
RB Leipzig;Besiktas JK;loss
积分规则
- 比赛结果对应列表中的第一支球队:
Besiktas JK;RB Leipzig;win→ Besiktas JK击败RB LeipzigAS Monaco;Besiktas JK;loss→ Besiktas JK击败AS MonacoRB Leipzig;AS Monaco;draw→ RB Leipzig与AS Monaco战平
- 获胜得3分,平局得1分,失利得0分
- 排名按积分降序排列;积分相同则按球队名称字母顺序排序
预期输出
Team | MP | W | D | L | P Besiktas JK | 6 | 4 | 2 | 0 | 14 FC Porto | 6 | 3 | 1 | 2 | 10 RB Leipzig | 6 | 2 | 1 | 3 | 6 AS Monaco | 6 | 0 | 2 | 4 | 2
问题:现有PHP代码无法生成正确排名
我用以下代码读写tournament.txt文件,但得不到符合要求的排名结果,该怎么修复?
tournament.txt内容
RB Leipzig;AS Monaco;draw FC Porto;Besiktas JK;loss Besiktas JK;RB Leipzig;win AS Monaco;FC Porto;loss AS Monaco;Besiktas JK;loss RB Leipzig;FC Porto;win Besiktas JK;AS Monaco;draw FC Porto;RB Leipzig;win Besiktas JK;FC Porto;draw AS Monaco;RB Leipzig;loss FC Porto;AS Monaco;win RB Leipzig;Besiktas JK;loss
tournament.php代码
<?php $lines = file('tournament.txt'); foreach ($lines as $line) { $parts = explode(';', $line); $teams[$parts[0]][] = $parts[2]; $teams[$parts[1]][] = $parts[2]; } uksort($teams, function ($a, $b) use ($teams) { $aPoints = 0; $bPoints = 0; foreach ($teams[$a] as $result) { if ($result == 'win') { $aPoints += 3; } elseif ($result == 'draw') { $aPoints += 1; } } foreach ($teams[$b] as $result) { if ($result == 'win') { $bPoints += 3; } elseif ($result == 'draw') { $bPoints += 1; } } foreach ($teams[$a] as $result) { if ($result == 'loss') { $aPoints += 0; $bPoints += 3; } } foreach ($teams[$b] as $result) { if ($result == 'loss') { $aPoints += 3; $bPoints += 0; } } if ($aPoints == $bPoints) { return $a <=> $b; } return $bPoints <=> $aPoints; }); $fp = fopen('tournament.txt', 'w'); fwrite($fp, "Team | MP | W | D | L | P "); foreach ($teams as $team => $results) { $mp = count($results); $w = 0; $d = 0; $l = 0; foreach ($results as $result) { if ($result == 'win') { $w++; } elseif ($result == 'draw') { $d++; } else { $l++; } } $p = $w * 3 + $d; fwrite($fp, sprintf("%-30s| %2d | %2d | %2d | %2d | %2d ", $team, $mp, $w, $d, $l, $p)); } fclose($fp); ?>
问题分析与修复方案
核心问题
- 赛事结果存储错误:原代码将第二支球队的结果直接复制为第一支球队的结果,完全不符合规则。比如
FC Porto;Besiktas JK;loss,FC Porto的结果是loss,对应Besiktas JK的结果应该是win,而非loss。 - 排序逻辑混乱:排序函数中重复计算积分,还错误地给对比球队叠加积分,导致排名计算完全错误。
修正后的代码
<?php // 初始化球队统计数据容器 $teams = []; // 读取赛事文件,忽略空行与换行符 $lines = file('tournament.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($lines as $line) { $parts = array_map('trim', explode(';', $line)); $team1 = $parts[0]; $team2 = $parts[1]; $result1 = $parts[2]; // 初始化未记录的球队数据 foreach ([$team1, $team2] as $team) { if (!isset($teams[$team])) { $teams[$team] = ['mp' => 0, 'w' => 0, 'd' => 0, 'l' => 0, 'p' => 0]; } } // 更新两队总场次 $teams[$team1]['mp']++; $teams[$team2]['mp']++; // 根据第一队结果更新两队的胜负平与积分 switch ($result1) { case 'win': $teams[$team1]['w']++; $teams[$team1]['p'] += 3; $teams[$team2]['l']++; break; case 'loss': $teams[$team1]['l']++; $teams[$team2]['w']++; $teams[$team2]['p'] += 3; break; case 'draw': $teams[$team1]['d']++; $teams[$team1]['p'] += 1; $teams[$team2]['d']++; $teams[$team2]['p'] += 1; break; } } // 排序:先按积分降序,积分相同按球队名称升序 uksort($teams, function ($teamA, $teamB) use ($teams) { if ($teams[$teamA]['p'] !== $teams[$teamB]['p']) { return $teams[$teamB]['p'] <=> $teams[$teamA]['p']; } return $teamA <=> $teamB; }); // 写入结果到文件 $fp = fopen('tournament.txt', 'w'); // 写入表头与分隔线 fwrite($fp, sprintf("%-25s | %2s | %2s | %2s | %2s | %2s\n", 'Team', 'MP', 'W', 'D', 'L', 'P')); fwrite($fp, str_repeat('-', 55) . "\n"); // 写入每队统计数据 foreach ($teams as $name => $stats) { fwrite($fp, sprintf("%-25s | %2d | %2d | %2d | %2d | %2d\n", $name, $stats['mp'], $stats['w'], $stats['d'], $stats['l'], $stats['p'] )); } fclose($fp); ?>
修复说明
- 正确映射赛事结果:处理每场比赛时,根据第一队的结果,对应更新第二队的胜负平数据,保证数据逻辑符合规则。
- 提前计算统计值:读取赛事数据时直接计算每队的场次、胜平负、积分,避免后续重复计算,提升效率与准确性。
- 简化排序逻辑:使用
uksort直接按球队名称为键排序,逻辑清晰:先比较积分降序,积分相同则按名称升序。 - 优化输出格式:统一表头与内容的格式化,确保和预期输出一致,同时处理了空白字符与换行符的问题。
内容的提问来源于stack exchange,提问作者kalawaja
相关产品推荐
相关产品推荐

