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

使用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 Leipzig
    • AS Monaco;Besiktas JK;loss → Besiktas JK击败AS Monaco
    • RB 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);

?>

问题分析与修复方案

核心问题

  1. 赛事结果存储错误:原代码将第二支球队的结果直接复制为第一支球队的结果,完全不符合规则。比如FC Porto;Besiktas JK;loss,FC Porto的结果是loss,对应Besiktas JK的结果应该是win,而非loss。
  2. 排序逻辑混乱:排序函数中重复计算积分,还错误地给对比球队叠加积分,导致排名计算完全错误。

修正后的代码

<?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);

?>

修复说明

  1. 正确映射赛事结果:处理每场比赛时,根据第一队的结果,对应更新第二队的胜负平数据,保证数据逻辑符合规则。
  2. 提前计算统计值:读取赛事数据时直接计算每队的场次、胜平负、积分,避免后续重复计算,提升效率与准确性。
  3. 简化排序逻辑:使用uksort直接按球队名称为键排序,逻辑清晰:先比较积分降序,积分相同则按名称升序。
  4. 优化输出格式:统一表头与内容的格式化,确保和预期输出一致,同时处理了空白字符与换行符的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:32:08