用Java更新游戏记录

用Java更新游戏记录,java,algorithm,sorting,Java,Algorithm,Sorting,我们的比赛记录如下: 允许玩家在不同级别玩游戏,并保留一个高分表以显示前10名游戏记录列表。highscore表上的每个游戏记录都包含一组属性,例如,玩家的姓名、获得的总分以及获得分数的级别。游戏记录列表通常按得分从高到低排序,表示玩家从高到低的等级 我们必须实施 public GameRecord[] updateGameRecords(GameRecord[] oldRecords, GameRecord newRecord) 以以下方式: 如果存在与newRecord具有相同名称和级

我们的比赛记录如下:

允许玩家在不同级别玩游戏,并保留一个高分表以显示前10名游戏记录列表。highscore表上的每个游戏记录都包含一组属性,例如,玩家的姓名、获得的总分以及获得分数的级别。游戏记录列表通常按得分从高到低排序,表示玩家从高到低的等级

我们必须实施

 public GameRecord[] updateGameRecords(GameRecord[] oldRecords, GameRecord newRecord)
以以下方式:

  • 如果存在与newRecord具有相同名称和级别的记录,那么如果newRecord具有更高的分数,我们将更新该记录,然后对oldRecords进行排序并返回它。 否则,请转至步骤2
  • 如果与newRecord具有相同级别的记录数小于10,则我们将新记录插入oldRecords并对其进行排序,然后返回。否则,请转至步骤3

  • 如果有任何记录在与newRecord相同的级别上具有较差的分数,则我们将该记录替换为该级别的最低分数,因为给定级别的记录数不能超过10,然后我们排序并返回旧记录

  • 到目前为止,这一直是我的代码:

    public GameRecord[] updateGameRecords(GameRecord[] oldRecords, GameRecord newRecord) {
        int index = -1, r = 0;
        boolean break_loop = false, same_name_level = false;
        for (int i = 0; i < oldRecords.length; ++i) {
            while (i < oldRecords.length && newRecord.getLevel() < oldRecords[i].getLevel()) {
                ++i;
                continue;
            }
            while (i < oldRecords.length && i < oldRecords.length && newRecord.getLevel() == oldRecords[i].getLevel()) {
                if (r == 0)
                    index = i;
                ++r;//r is number of records with same level
                if (!break_loop && newRecord.getName().equals(oldRecords[i].getName())) {
                    same_name_level = true;
                    break_loop = true;
                    if (newRecord.getScore() > oldRecords[i].getScore()) {
                        oldRecords[i].setScore(newRecord.getScore());
                    }
                }
                ++i;
            }
            if (break_loop == true)
                break;
        }
    
        if (break_loop == true) {
            Util.sort(oldRecords);
            return oldRecords;
        }
    
        if (r > 0 && r < 10 && same_name_level == false) {
            GameRecord[] temp = oldRecords.clone();
            oldRecords = new GameRecord[oldRecords.length + 1];
            System.arraycopy(temp, 0, oldRecords, 0, temp.length);
            oldRecords[temp.length] = newRecord;
            Util.sort(oldRecords);
            return oldRecords;
        }
    
        if (r == 10) {
            if (oldRecords[index + 9].getScore() < newRecord.getScore())
                oldRecords[index + 9].setScore(newRecord.getScore());
            Util.sort(oldRecords);
            return oldRecords;
        }
    
        if (r == 0) {
            GameRecord[] temp = oldRecords.clone();
            oldRecords = new GameRecord[oldRecords.length + 1];
            System.arraycopy(temp, 0, oldRecords, 0, temp.length);
            oldRecords[temp.length] = newRecord;
            Util.sort(oldRecords);
            return oldRecords;
        } else
            return oldRecords;
    }
    
    public GameRecord[]updateGameRecords(GameRecord[]旧记录,GameRecord新记录){
    int-index=-1,r=0;
    布尔中断循环=false,相同名称\u级别=false;
    对于(int i=0;ioldRecords[i].getScore()){
    oldRecords[i].setScore(newRecord.getScore());
    }
    }
    ++一,;
    }
    if(break_loop==true)
    打破
    }
    if(break_loop==true){
    Util.sort(旧记录);
    归还旧记录;
    }
    如果(r>0&&r<10&&same\u name\u level==false){
    GameRecord[]temp=oldRecords.clone();
    oldRecords=新游戏记录[oldRecords.length+1];
    系统阵列副本(临时,0,旧记录,0,临时长度);
    oldRecords[温度长度]=新记录;
    Util.sort(旧记录);
    归还旧记录;
    }
    如果(r==10){
    if(oldRecords[index+9].getScore()
    它工作正常,但这是一个线性时间复杂度代码,即需要O(oldRecords.length)+Util.sort()函数花费的时间,这使得总运行时间非线性

    你能给我推荐一个线性时间算法吗。

    O(n)解决方案是:

    static final int MAX = 10;
    
    static void bubbling(int[] recs) {
        for (int i = recs.length - 1; i > 0; --i)
            if (recs[i] > recs[i - 1]) {
                int temp = recs[i];
                recs[i] = recs[i - 1];
                recs[i - 1] = temp;
            }
    }
    
    static int[] updateRecord(int[] oldRecs, int newRec) {
        int oldLen = oldRecs.length;
        int newLen = oldLen < MAX ? oldLen + 1 : MAX;
        int[] newRecs = new int[newLen];
        System.arraycopy(oldRecs, 0, newRecs, 0, oldLen);
        if (newLen > oldLen || newRec >= newRecs[newLen - 1]) {
            newRecs[newLen - 1] = newRec;
            bubbling(newRecs);
        }
        return newRecs;
    }
    
    static final int MAX=10;
    静态气泡(int[]recs){
    对于(int i=recs.length-1;i>0;--i)
    if(recs[i]>recs[i-1]){
    int temp=recs[i];
    recs[i]=recs[i-1];
    记录[i-1]=温度;
    }
    }
    静态int[]更新记录(int[]旧记录,int新记录){
    int oldLen=oldRecs.length;
    int newLen=oldLenoldLen | | newRec>=newRecs[newLen-1]){
    newRecs[newLen-1]=newRec;
    起泡(newRecs);
    }
    返回新记录;
    }
    

    GameRecord
    更改为
    int
    以简化问题。

    要在插入或更新记录时维护排序列表,无需再次对整个列表排序;将此记录移动到适当的位置就足够了。此外,因为我们从不改变水平,只增加分数,我们知道这项记录只会上升

    也就是说,插入或更新记录后,我将调用以下方法:

    void moveToProperPlace(GameRecord[] records, int index) {
        int newIndex = findCorrectIndex(records, index);
        if (newIndex != index) {
            GameRecord record = records[index];
            System.arrayCopy(records, newIndex, records, newIndex + 1, index - newIndex);
            records[newIndex] = record;
        }
    }
    
    int findCorrectIndex(records, index) {
        int i = index;
        do {
            i--;
        } while (i >= 0 && higher(records[index], records[i]);
        return i + 1;
    }
    
    boolean higher(GameRecord x, GameRecord y) {
        return x.getScore() > y.getScore() || (x.getScore() == y.getScore && x.getLevel() > y.getLevel());
    }
    
    由于预排序数据非常常见,因此,如果标准库中设计良好的排序实现检测到数据几乎已排序,则实际上可能会退回到这种插入排序,从而为只有常量元素位于错误位置的输入提供O(n)排序,否则为O(n logn)。特别是,它们以这种方式实现。如果您的
    Util.sort
    也是这样实现的,那么您的算法已经是O(n)


    在任何情况下,除非每秒要记录数千个关卡和数百万个游戏,否则O(n)和O(n log n)之间的差异不太可能对程序的执行时间产生明显影响。

    了解Util.sort如何对数组排序吗?游戏记录有可比性吗?GameRecord的内部数据类型是什么?你不能只保留前10条记录吗?这样,您的算法(应该是O(nlogn)复杂度)在非常小的时间内运行time@TobiasStoeckmann No不可比较,内部数据类型为字符串表示名称,整数表示分数和级别。Util.sort使用quicksort和mergesort,两者都不是线性的。接下来,我进一步假设oldRecords作为参数提供时已经进行了排序。我的假设是基于