題目描述

為了進行排序,比較器被用來比較兩個物件。這個題目將會測驗您對Java比較器的認知。



在比賽中有N個玩家。您將會得到他們的名稱和分數,接著您需要以反序的方式排序這些玩家分數。如果兩個玩家的分數一樣,那麼玩家名稱之辭典排序在前的玩家要排在前面的位置。

原題網址

https://www.hackerrank.com/challenges/java-comparator

輸入格式

第一行包含一個整數N,表示玩家的數量。接下來的N行為每個玩家的名稱和分數,用空格字元隔開。

兩個不同的玩家可以用有相同的名稱,玩家的名稱使用小寫英文字母組成。玩家的分數範圍在0到1000之間(包含0和1000)。

輸出格式

排序之後分行輸出每個玩家的名稱和分數,用空格字元隔開。

範例輸入

5
amy 100
david 100
heraldo 50
aakansha 75
aleksa 150

範例輸出

aleksa 150
amy 100
david 100
aakansha 75
heraldo 50

解題概念

程式第28行使用了check物件作為排序陣列的Comparator,因此必須撰寫Checker類別,並實作出Comparator介面的compare方法。

compare方法若傳回值小於0,表示第一個傳入的參數在邏輯上小於第二個傳入的參數;若等於0,表示兩個參數邏輯相等;若大於0,表示第一個傳入的參數在邏輯上大於第二個傳入的參數。所以當第一個玩家的分數比第二個玩家的分數大時,要傳回-1;小於時,要傳回0;若等於的話,要再比較名稱的順序。由於名稱是字串,所以可以直接使用字串的compareTo方法來比較辭典排列順序。

參考答案

import java.util.*;

class Player {

    String name;
    int score;

    Player(String name, int score) {
        this.name = name;
        this.score = score;
    }
}

class Solution {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        Player player[] = new Player[n];
        Checker checker = new Checker();

        for (int i = 0; i < n; i++) {
            player[i] = new Player(scan.next(), scan.nextInt());
        }
        scan.close();

        Arrays.sort(player, checker);
        for (int i = 0; i < player.length; i++) {
            System.out.printf("%s %s\n", player[i].name, player[i].score);
        }
    }
}

class Checker implements Comparator<Player> {

    @Override
    public int compare(Player a, Player b) {
        if (a.score > b.score) {
            return -1;
        } else if (a.score < b.score) {
            return 1;
        }
        return a.name.compareTo(b.name);
    }
}