最近面试的时候面试官问了一个很有趣的题,当时答得不是很好逻辑有些混乱。
后面下来自己总结了一下,其实考的就是冒泡和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的函数进行运算了
$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);
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.