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