选修课(java)

选修课

难度:★★

别看代码多大部分都是输入输出,不说了,java的泪。主要还是排序。

选修课

知识点字符串哈希表排序

时间限制:1s 空间限制:256MB 限定语言:不限

题目描述:

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

输入描述:

第一行为第一门选修课学生的成绩,第二行为第二门选修课学生的成绩,每行数据中学生之间以英文分号分隔,每个学生的学号和成绩以英文逗号分隔,学生学号的格式为8位数字(2位院系编号+入学年份后2位+院系内部1位专业编号+所在班级3位学号),学生成绩的取值范围为[0,100]之间的整数,两门选修课选修学生数的取值范围为[1-2000]之间的整数。

输出描述:

同时选修了两门选修课的学生的学号,如果没有同时选修两门选修课的学生输出NULL,否则,先按照班级划分,班级编号小的先输出,每个班级先输出班级编号(学号前五位),然后另起一行输出这个班级同时选修两门选修课的学生学号,学号按照要求排序(按照两门选修课成绩和的降序,成绩和相同时按照学号升序),学生之间以英文分号分隔。

示例1

输入:

01202021,75;01201033,95;01202008,80;01203006,90;01203088,100

01202008,70;01203088,85;01202111,80;01202021,75;01201100,88

输出:

01202

01202008;01202021

01203

01203088

说明:

同时选修了两门选修课的学生01202021、01202008、01203088,这三个学生两门选修课的成绩和分别为150、150、185,01202021、01202008属于01202班的学生,按照成绩和降序,成绩相同时按学号升序输出的结果为01202008;01202021,01203088属于01203班的学生,按照成绩和降序,成绩相同时按学号升序输出的结果为01203088,01202的班级编号小于01203的班级编号,需要先输出。

示例2

输入:

01201022,75;01202033,95;01202018,80;01203006,90;01202066,100

01202008,70;01203102,85;01202111,80;01201021,75;01201100,88

输出:

NULL

说明:

没有同时选修了两门选修课的学生,输出NULL。

解题思路:

  1. 使用Scanner对象读取输入的两门选修课学生的成绩。
  2. 创建一个HashMap用于存储选修了两门课的学生信息,其中键为班级编号,值为对应班级的学生列表。
  3. 遍历第一门选修课学生的成绩,并与第二门选修课学生的成绩进行比较,找到同时选修了两门课的学生。
  4. 将同时选修两门课的学生信息存储到对应班级的学生列表中。
  5. 如果没有符合要求的学生,输出"NULL"。
  6. 对班级进行排序,并按要求输出班级编号和学生学号。

JAVA代码:

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] one = sc.nextLine().split(";");
        String[] two = sc.nextLine().split(";");
        sc.close();

        // 创建一个 HashMap 用于存储选修了两门课的学生信息
        Map<String, List<Student>> map = new HashMap<>();
        for (String score : one) {
            String[] parts = score.split(",");
            String studentId = parts[0];
            int score1 = Integer.parseInt(parts[1]);
            // 使用学生学号作为键,直接存储到 HashMap 中
            map.put(studentId, new ArrayList<>());
            map.get(studentId).add(new Student(studentId, score1));
        }

        for (String score : two) {
            String[] parts = score.split(",");
            String studentId = parts[0];
            int score2 = Integer.parseInt(parts[1]);
            // 如果学生学号存在于 HashMap 中,则更新第二门选修课成绩
            if (map.containsKey(studentId)) {
                map.get(studentId).get(0).score2 = score2;
            }
        }

        List<Student> selectedStudents = new ArrayList<>();
        for (List<Student> students : map.values()) {
            // 将同时选修了两门课的学生添加到选中的学生列表中
            if (students.get(0).score2 > 0) {
                selectedStudents.addAll(students);
            }
        }

        if (selectedStudents.isEmpty()) {
            System.out.println("NULL");
        } else {
            // 对选中的学生列表进行排序,首先按照总成绩降序排序,然后按照学生学号升序排序
            selectedStudents.sort(Comparator
                    .comparing(Student::getScoreSum).reversed()
                    .thenComparing(Student::getStudentId));

            // 使用 TreeMap 对班级进行排序,保证班级编号的升序输出
            Map<String, List<Student>> classMap = new TreeMap<>();
            for (Student student : selectedStudents) {
                String classId = student.getStudentId().substring(0, 5);
                // 将学生添加到对应班级的学生列表中
                classMap.putIfAbsent(classId, new ArrayList<>());
                classMap.get(classId).add(student);
            }

            for (Map.Entry<String, List<Student>> entry : classMap.entrySet()) {
                // 输出班级编号
                System.out.println(entry.getKey());
                StringBuilder res = new StringBuilder();
                for (Student student : entry.getValue()) {
                    // 输出学生学号,并使用分号分隔
                    res.append(student.getStudentId()).append(";");
                }
                // 移除最后一个分号,并输出结果
                System.out.println(res.substring(0, res.length() - 1));
            }
        }
    }

    // 学生类
    static class Student {
        String studentId; // 学生学号
        int score1; // 第一门选修课成绩
        int score2; // 第二门选修课成绩

        public Student(String studentId, int score1) {
            this.studentId = studentId;
            this.score1 = score1;
            this.score2 = -1; // 初始值设为 -1 表示未选修第二门课
        }

        public int getScoreSum() {
            // 返回两门选修课成绩之和
            return score1 + score2;
        }

        public String getStudentId() {
            return studentId;
        }
    }
}

代码说明:

代码思路和实现说明如下:

  • 首先使用Scanner对象从标准输入中读取两门选修课学生的成绩,分别保存在onetwo数组中。
  • 创建一个HashMap,用于存储选修了两门课的学生信息。键为学生的学号,值为对应学生的成绩信息。
  • 遍历one数组,将每个学生的学号和成绩存储在HashMap中。
  • 遍历two数组,对于每个学生的学号,如果在HashMap中存在,则更新该学生的第二门选修课成绩。
  • 创建一个selectedStudents列表,用于存储同时选修了两门课的学生。
  • 遍历HashMap中的值,如果学生的第二门选修课成绩大于0,则将该学生添加到selectedStudents列表中。
  • 如果selectedStudents列表为空,表示没有同时选修两门课的学生,输出"NULL"。
  • 否则,对selectedStudents列表进行排序,首先按照总成绩降序排序,然后按照学生学号升序排序。
  • 创建一个classMap,用于按照班级将选中的学生进行分组。
  • 遍历selectedStudents列表,将学生按照班级编号添加到classMap中。
  • 使用TreeMapclassMap进行排序,按照班级编号升序输出班级信息。
  • 遍历classMap,输出班级编号和对应班级的学生学号。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜柠函

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值