• 使用explode拆分字符串,获取输入文件名和行号
  • 使用关联数组保存数据,“文件名.分隔符.行号”拼接的字符串作键名用来去重
  • 使用substr($fileName,-8)截取最后输出的文件名

现在最大的问题就是获取出现次数最高的 8 条数据了,arsort排序在遇到键值相同时,键名会按照升序排列,就会出现当出现次数相同时,无法保证先输入的条目先输出。所以这里采用每次取一个最大值,然后把最大值从数据集中删除,然后再取最大值的方式。

$array = [];
$order = [];
$index = 0;
while (true) {
    $line = trim(fgets(STDIN), PHP_EOL);
    if ($line == '') {
        break;
    }
    $lineExplodes = explode(' ', $line);
    $fileName = explode('\\', $lineExplodes[0]);
    $name = end($fileName);
    $fileIndex = $name . '@' . $lineExplodes[1];
    if (isset($array[$fileIndex])) {
        $array[$fileIndex]['count'] = $array[$fileIndex]['count'] + 1;
    } else {
        $array[$fileIndex] = [
            'file' => $name,
            'line' => $lineExplodes[1],
            'count' => 1,
            'sort' => $index
        ];
    }
    $index++;
}
function popMax($array)
{
    $max = null;
    $fileIndex = null;
    foreach ($array as $index2 => $item2) {
        if (empty($max)) {
            $max = $item2;
            $fileIndex = $index2;
            continue;
        }
        if ($max['count'] == $item2['count']) {
            if ($max['sort'] > $item2['sort']) {
                $max = $item2;
                $fileIndex = $index2;
            }
        } else {
            if ($max['count'] < $item2['count']) {
                $max = $item2;
                $fileIndex = $index2;
            }
        }
    }
    return compact('max', 'fileIndex');
}

$count = 0;
while ($count < 8) {
    $max = popMax($array);
    unset($array[$max['fileIndex']]);
    echo substr($max['max']['file'], -16) . ' ' . $max['max']['line'] . ' ' . $max['max']['count'] . PHP_EOL;
    $count++;
}