You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android学生成绩排名问题:基于索引中位数的排名修正需求

学生排名中位数计算逻辑修正

需求说明

按分数降序排列学生数据,分数相同的学生以他们的索引(1-based序号)中位数作为共同排名,具体规则:

  • 3个同分数学生(索引1、2、3):中位数为2 → 排名设为2.0
  • 2个同分数学生(索引4、5):中位数为(4+5)÷2=4.5 → 排名设为4.5
  • 5个同分数学生(索引7-11):中位数为9 → 排名设为9.0

现有代码问题

当前基于Firebase+RecyclerView的Android代码仅能正确计算前5个学生的分组排名,其余分组计算错误:

  • 6个同分数学生(索引6-11):正确中位数应为8.5,实际得到8.0
  • 部分2个同分数学生:正确排名应为12.5,实际得到12.0

错误原因

代码中使用整数除法计算中位数,且基于0-based的列表索引而非真实的1-based索引:

double medianIndex = (startIndex + endIndex - 1) / 2; // 整数除法会截断小数
double rank = medianIndex + 1;

例如2个学生的分组,列表索引startIndex=3、endIndex=5,整数运算(3+5-1)/2=3,加1后得到4.0,而非正确的4.5。

修正后的代码

核心修改:改用真实的1-based索引计算中位数,强制使用浮点除法保留小数:

public class ViewStudentScores extends AppCompatActivity {

private DatabaseReference databaseReference;
private StudentAdapter studentAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_student_scores);

    RecyclerView recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    studentAdapter = new StudentAdapter();
    recyclerView.setAdapter(studentAdapter);
    databaseReference = FirebaseDatabase.getInstance().getReference("students");
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            List<Student> students = new ArrayList<>();
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Student student = snapshot.getValue(Student.class);
                students.add(student);
            }

            // 按分数降序排序
            Collections.sort(students, new Comparator<Student>() {
                @Override
                public int compare(Student student1, Student student2) {
                    return Double.compare(student2.getScore(), student1.getScore());
                }
            });

            // 为同分数学生分配基于索引中位数的排名
            int totalStudents = students.size();
            int startIndex = 0;
            while (startIndex < totalStudents) {
                int endIndex = startIndex + 1;
                // 找到当前分数分组的结束位置
                while (endIndex < totalStudents && students.get(startIndex).getScore() == students.get(endIndex).getScore()) {
                    endIndex++;
                }
                // 计算当前分组的真实1-based索引范围
                int firstRealIndex = startIndex + 1;
                int lastRealIndex = endIndex; // 因为endIndex是下一组的起始,当前组最后一个的真实索引是endIndex
                // 计算中位数排名(浮点除法保留小数)
                double medianRank = (firstRealIndex + lastRealIndex) / 2.0;

                // 为当前分组的所有学生设置排名
                for (int i = startIndex; i < endIndex; i++) {
                    students.get(i).setRank(medianRank);
                }

                startIndex = endIndex;
            }

            // 更新RecyclerView数据
            studentAdapter.setStudents(students);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            // 处理数据库错误
        }
    });
}

验证说明

  • 6个同分数学生(索引6-11):(6+11)/2.0=8.5,符合预期
  • 2个同分数学生(索引12、13):(12+13)/2.0=12.5,符合预期
  • 奇数个分组(如3个、5个):计算结果与需求完全匹配

内容的提问来源于stack exchange,提问作者F.joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 07:10:00