MENU

一道有趣的面试题【php数组求并列】

September 11, 2020 • php阅读设置

最近面试的时候面试官问了一个很有趣的题,当时答得不是很好逻辑有些混乱。
后面下来自己总结了一下,其实考的就是冒泡和php函数使用。

题目:
假设有一组学生成绩数组,要求对其进行从大到小的排序,并且求成绩相同的同学的并列名次。

通俗的讲,张三90分,李四90分,王五80分,赵六75分,刘七75分,

最后排序下来的结果是,张三李四并列第一,王五第二,赵六和刘七并列第三。

实现思路一:冒泡排序

1.先不用管名次的事,先按从大到小把原数组进行排序.
成绩数组:

$students = [
    ['name' => 'aa', 'score' => 80],
    ['name' => 'bb', 'score' => 81],
    ['name' => 'cc', 'score' => 90],
    ['name' => 'dd', 'score' => 99],
    ['name' => 'ee', 'score' => 91],
    ['name' => 'ff', 'score' => 70],
    ['name' => 'gg', 'score' => 72],
    ['name' => 'hh', 'score' => 72],
    ['name' => 'ii', 'score' => 80],
    ['name' => 'jj', 'score' => 99],
];

第一轮冒泡排序:

// 先冒泡进行第一轮排列
$studentsLen = count($students);
for ($i = 0; $i < $studentsLen; $i++) {
    for ($j = $i + 1 ; $j < $studentsLen; $j++) {
        if ($students[$i]['score'] < $students[$j]['score']) {
            $tmp = $students[$i];
            $students[$i] = $students[$j];
            $students[$j] = $tmp;
        }
    }
}

第一轮排序后,再进行一轮循环,对名次进行排定。
实现思路 X[i] == X[i-1]的时候,X[i]就等于就等于上一个X[i-1]的名次

$deep = 1;
for ($i = 0; $i < $studentsLen; $i++) {
   if ($i == 0) {
       $students[$i]['deep'] = $deep; // 因为之前已经排好序了,所以数组第一位肯定是最高分,排名默认给1
   } else if ($students[$i]['score'] == $students[$i-1]['score']) { // 如果当前坐标x数组的分数跟上一个分数一致,那么并列上一个数组的排名
       $students[$i]['deep'] = $deep;
   } else { // 否则当前数组的排名++
       $students[$i]['deep'] = ++$deep;
   }
}

实现思路二:纯函数排序

$scores = array_column($students,"score");
$scores = array_unique($scores);
rsort($scores);// 先排序分数

foreach ($students as $key => &$val){
    $v["deep"] = array_search($val['score'],$scores) +1; // 从分数数组中找到坐标.
}
$tmpDeep = array_column($students, 'deep'); // 根据排名再排序.
array_multisort($tmpDeep, SORT_ASC, $students);

这个方案就是纯利用php的函数进行运算了

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. s s

    $scores = array_column($students, 'score');
    array_multisort($scores, SORT_DESC, $students);
    $now = 0;
    foreach ($students as $key => &$student) {
    if (!$now || $student['score'] !== $students[$key - 1]['score']) $now++;
    $student['deep'] = $now;
    }
    unset($student);

  2. UMAIR AHMAD SHAD UMAIR AHMAD SHAD

    I am looking for a developer to work on my project, would be really nice to work with you. please reply to me soon when you see my message.