首页 > 其他分享 >选修课-字符串哈希表排序

选修课-字符串哈希表排序

时间:2023-11-02 12:12:34浏览次数:32  
标签:map 选修课 班级 mapList score 哈希 排序

题目:现有两门选修课,每门选修课都有一部分学生选修,每个学生都有选修课的成绩,需要你找出同时选修了两门选修课的学生,先按照班级进行划分,班级编号小的先输出,每个班级按照两门选修课成绩和的降序排序,成绩相同时按照学生的学号升序排序。

学号+成绩组成,中间,分割;要求:1.选出同时选修两门课的学生2.先按班级划分,班级编号小的先输出3.每个班级按照两门修选课成绩和降序排列4.成绩相同按照学号的升序排序
学号组成:总共8位数=2院系编号+2入学年份后两位+1院系内部专业编号+3所在班级的学号,班级为学号的前5位

思路:

(1)先定义学生类,实现comparable接口,重写compareTo方法(2)定义学号和成绩两个字段(3)重写方法进行分数比较,分数大的排在前面;分数相同再进行学号比较,升序排列;学号相等,则第一个学生排在前面
(2)主类中:2.1先将每门课信息集合到数组里;2.2分离出学号进行对比;2.3如果同时选修了两门课,则计算总成绩,并将学生信息,总计加入到学生类;2.4最后加入到map中

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    String[] one = sc.nextLine().split(";");
    String[] two = sc.nextLine().split(";");

    Map<String, List<Student>> map = new HashMap<>();
    for(int i=0; i<one.length; i++){

        String[] oneStu = one[i].split(",");
        //学生学号
        String oneStuId = oneStu[0];

        for(int j=0; j<two.length; j++){

            String[] twoStu = two[j].split(",");
            //学生学号
            String twoStuId = twoStu[0];
            //同时选修两门课
            if(oneStuId.equals(twoStuId)){

                int oneStuScore = Integer.parseInt(oneStu[1]);
                int twoStuScore = Integer.parseInt(twoStu[1]);
                //总成绩
                int totalScore = oneStuScore + twoStuScore;
                //班级编号
                String cla = twoStuId.substring(0, 5);
                //学生信息
                Student student = new Student(oneStuId, totalScore);
                //如果有班级编号,则输入学生信息
                if(map.containsKey(cla)){
                    map.get(cla).add(student);
                }else {
                    //没有则将学生的班级编号和学生信息push进去
                    List<Student> list = new ArrayList<>();
                    list.add(student);
                    map.put(cla, list);
                }
            }
        }
    }

    if(map.size() == 0){
        //没有符合要求的
        System.out.println("NULL");
    }else {
        /**
         * 这行代码的作用是将 `map` 转换为一个 `List`,该 `List` 中的每个元素都是一个 `Map.Entry` 对象,其中包含了班级编号和对应的学生信息列表。
         * 解释如下:
         * `map.entrySet()` 方法返回一个 `Set<Map.Entry>`,该 `Set` 中包含了 `map` 中全部的键值对。而 `Map.Entry` 则是表示一个键值对的接口。
         * `ArrayList<>(map.entrySet())` 是将 `map.entrySet()` 返回的键值对集合转换成一个 `ArrayList` 对象,然后将其赋值给 `mapList` 变量。
         * 因此,`mapList` 变量就是一个包含了 `map` 中全部键值对的 `List` 对象,每个元素都是一个 `Map.Entry` 对象。
         * 这样处理之后,我们可以通过遍历 `mapList` 来访问 `map` 中的键值对,并对其进行排序或其他操作。
         * */
        List<Map.Entry<String, List<Student>>> mapList = new ArrayList<>(map.entrySet());
        /**
         *在这段代码中,返回-1和1是用来定义比较器的规则。比较器是用来对对象进行比较排序的工具。
         * 在这里,`mapList.sort()`的参数是一个Lambda表达式,用来比较两个键值对的键。如果第一个键(`a.getKey()`)小于第二个键(`b.getKey()`),则返回-1,表示第一个键应该排在前面;如果第一个键大于第二个键,则返回1,表示第一个键应该排在后面。这样可以通过对键进行排序,从而按照班级编号进行排序。
         * 在Java中,比较器返回负数表示第一个对象较小,返回正数表示第一个对象较大,返回0表示两个对象相等。
         * 总结起来,这段代码的作用是对 `mapList`(存储学生信息的列表)中的元素进行排序,按照班级编号进行升序排序。返回-1表示第一个元素应该排在前面,返回1表示第一个元素应该排在后面。
         * */
        mapList.sort((a,b) -> {
            if(a.getKey().compareTo(b.getKey()) < 0){
                return -1;
            }
            return 1;
        });

        for(Map.Entry<String, List<Student>> m : mapList){
            //输出班级编号
            System.out.println(m.getKey());
            String res = "";
            //对学生按照要求排序
            Collections.sort(m.getValue());
            for(Student s : m.getValue()){
                res += s.stuId + ";";
            }
            //再输出学号
            System.out.println(res.substring(0, res.length() - 1));
        }
    }

}

static class Student implements Comparable<Student> {

    String stuId;
    int score;

    public Student(String stuId, int score){
        this.stuId = stuId;
        this.score = score;
    }

    @Override
    public int compareTo(Student o) {
        if(this.score > o.score){
            return -1;
        }else if(this.score == o.score){
            if(this.stuId.compareTo(o.stuId) > 0){
                return 1;
            }
            return -1;
        }
        return 1;
    }
}

标签:map,选修课,班级,mapList,score,哈希,排序
From: https://www.cnblogs.com/xiaoyezilei/p/17805100.html

相关文章

  • 最大堆最小堆及堆排序
    堆这个数据结构在我大学的教材上没有讲解,但平时听说过堆排序什么的,无疑是要用到这个数据结构,所以本篇文章主要是总结下堆的概念和实现。堆概念在维基百科中,是这样定义堆的:堆(英语:Heap)是计算机科学中的一种特别的树状数据结构。若是满足以下特性,即可称为堆:“给定堆中任意节点P......
  • 归并排序
    //归并排序#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintN=1e6+5;intn,a[N],b[N];voidh(intl1,intr1,intl2,intr2){//归操作//l1是第一部分的左指针r1是第一部分的右指针//l2是第二部分的左指针r2是第二部分的右指针 intt=1;......
  • 项目管理之项目质量管理MoSCoW(莫斯科)优先级排序法
    项目质量管理是项目管理中至关重要的一环,它贯穿于项目的整个生命周期,包括项目启动、规划、执行、监控和控制。为了确保项目工作的质量,我们需要从多个方面入手,以下是一些关于如何保障项目工作质量管理的内容。项目产品质量检查路径项目准备阶段来自客户的质量期望验收标准与容许偏差......
  • 你真的懂排序吗?
    冒泡排序交换次数就是逆序对个数,设每个位置的数字向前形成的逆序对是\(c_i\),那么有序即\(c_i=0\)对每个\(i\)都成立,考虑冒泡中一次交换\((i,i+1)(a_i>a_{i+1})\)对\(c\)的影响,那么就是\(c_i\leftarrowc_{i+1}-1,c_{i+1}\leftarrowc_i\),全局逆序对\(-1\)。[USACO18OP......
  • 刷题笔记——哈希表(C)
    215.数组中的第K个最大元素-力扣(LeetCode)给定整数数组nums和整数k,请返回数组中第**k**个最大的元素。请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。你必须设计并实现时间复杂度为O(n)的算法解决此问题。解题思路哈希+开放定址法注......
  • 归并排序 Acwing 787
    归并排序最重要的一部便是归并,我们的模板顺序为:定义一个中间值,将我们的区间范围一分为二,我们将这两部分看成两个数组,我们分别将这两个数组进行归并排序,并且定义一个新的数组,将这两个数组排序好后导入到这个新数组中,并最后将这个定义的数组输出为原数组,即可实现归并排序。1......
  • 使用函数的选择法排序
    本题要求实现一个用选择法对整数数组进行简单排序的函数。函数接口定义:voidsort(inta[],intn);其中a是待排序的数组,n是数组a中元素的个数。该函数用选择法将数组a中的元素按升序排列,结果仍然在数组a中。裁判测试程序样例:#include<stdio.h>#defineMAXN10voids......
  • 归并排序统计逆序对的数量
    788.逆序对的数量-AcWing题库 昨天刚好做到这题,发现网上题解都讲的不是很详细,于是决定自己手写一篇。 归并排序能统计逆序对的数量 为什么归并排序能统计逆序对数量???归并排序的特点是,以mid,mid+1为分界,对两边分别进行排序借助递归的性质先将两边都从小到大排好序,之......
  • 【算法题】2826. 将三个组排序
    题目:给你一个下标从0开始长度为n的整数数组nums。从0到n-1的数字被分为编号从1到3的三个组,数字i属于组nums[i]。注意,有的组可能是空的。你可以执行以下操作任意次:选择数字x并改变它的组。更正式的,你可以将nums[x]改为数字1到3中的任意一个。你将按......
  • 复仇归并排序
     归并排序就是,把一群数据一直分,一直分,分到不能再分之后,一个个按顺序把你们装进去 讲讲第一个难点,上面两个mergesort归并,其实这是一个把人给分开,分成两组,接着再分,再分。。。分到没办法分的时候,往下走。。。然后接着就是定义指针ijk,然后就有一个困扰了我很久的问题,为什么可......