首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現分數數組轉名次數組(處理並列名次)

     編輯:Java 相關知識

在競賽排名、成績統計等場景中,常需將分數數組轉換為對應的名次數組。本文介紹一種簡潔的實現方式:通過排序去重獲取唯一分值,再根據分值在排序陣列中的索引確定名次,自然處理並列名次情況。

問題定義

輸入:分數陣列 score = {4, 2, 5, 4}
輸出:名次陣列 rank = {2, 3, 1, 2}

規則:分數越高名次越前(數字越小);相同分數並列同一名次,下一名次順延(如兩個第 2 名,下一個是第 4 名)。

核心算法思路

  1. 將所有分數加入 List 並去重
  2. 升序排序後反轉,得到降序唯一分值陣列
  3. 遍歷原分數陣列,查找每個分值在唯一分值陣列中的索引,名次 = 索引 + 1

完整代碼實現

package test01;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ScoreRank {

    // 列印陣列輔助方法
    public static void show(int[] arr) {
        for (int x : arr) System.out.print(x + " ");
        System.out.println();
    }

    /**
     * 根據分數陣列計算名次陣列
     * @param score 分數陣列
     * @return 名次陣列(相同分數並列同一名次)
     */
    public static int[] scoreRank(int[] score) {
        // 1. 去重收集唯一分值
        List<Integer> uniqueScores = new ArrayList<>();
        for (int s : score) {
            if (!uniqueScores.contains(s)) {
                uniqueScores.add(s);
            }
        }

        // 2. 升序排序後反轉 = 降序
        Collections.sort(uniqueScores);
        Collections.reverse(uniqueScores);
        // 現在 uniqueScores 如 [5, 4, 2] 對應第 1、2、3 名

        // 3. 映射原分數到名次
        int[] rank = new int[score.length];
        for (int i = 0; i < score.length; i++) {
            // indexOf 返回首次出現位置,+1 即為名次
            rank[i] = uniqueScores.indexOf(score[i]) + 1;
        }
        return rank;
    }

    public static void main(String[] args) {
        int[] score = {4, 2, 5, 4};
        int[] rank = scoreRank(score);

        System.out.print("原始分數:");
        show(score);  // 4 2 5 4
        System.out.print("對應名次:");
        show(rank);   // 2 3 1 2
    }
}

執行結果

原始分數:4 2 5 4
對應名次:2 3 1 2

算法分析

優化版本(大數據量適用)

使用 TreeSet 自動去重排序,HashMap 快速查找名次:


import java.util.*;

public static int[] scoreRankOptimized(int[] score) {
    // 1. TreeSet 自動去重 + 降序排序
    TreeSet<Integer> sortedUnique = new TreeSet<>(Collections.reverseOrder());
    for (int s : score) sortedUnique.add(s);
    
    // 2. 建立分值 -> 名次 映射
    Map<Integer, Integer> scoreToRank = new HashMap<>();
    int rank = 1;
    for (int s : sortedUnique) {
        scoreToRank.put(s, rank++);
    }
    
    // 3. O(1) 查找映射
    int[] result = new int[score.length];
    for (int i = 0; i < score.length; i++) {
        result[i] = scoreToRank.get(score[i]);
    }
    return result;
}

優化後複雜度:時間 O(n log n),空間 O(n)

擴展:不同排名規則處理

指標複雜度說明
時間複雜度O(n²)List.contains 和 indexOf 皆為 O(n),n 為元素個數
空間複雜度O(n)額外儲存唯一分值 List
規則名稱並列處理示例 (分數: 100, 90, 90, 80)
標準競爭排名 (1224)並列佔位,下一名順延1, 2, 2, 4
修正競爭排名 (1334)並列取平均或最小1, 2.5, 2.5, 4
密集排名 (1223)並列不佔位,下一名緊接1, 2, 2, 3
序數排名 (1234)無並列,按原序區分1, 2, 3, 4

本文實現的是標準競爭排名 (1224),最符合一般直覺。

總結

分數轉名次是常見業務邏輯,關鍵在於「去重排序 + 索引映射」。小數據量用 List 簡潔明瞭;大數據量建議用 TreeSet + HashMap 優化查找效能。理解不同排名規則差異,才能根據業務選擇正確算法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved