7-1 找到出勤最多的人(答案附注释)java

这段代码展示了如何用Java编写程序,通过读取输入的出勤记录,使用HashMap和ArrayList计算并输出出勤次数最多的学员。

原题 

7-1 找到出勤最多的人

分数 10

全屏浏览题目

切换布局

作者 abc618382

单位 河北科技大学

根据教师的花名册,找到出勤最多的人。

输入格式:

出勤记录单行给出,数据直接使用空格分割。

输出格式:

单行输出(若有多人,人名直接使用空格分割,结尾处没有空格)。

输入样例:

在这里给出一组输入。例如:

zs ls ww ml zs ls ml zs ww

输出样例:

在这里给出相应的输出。例如:

zs

答案 

 

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String name = sc.nextLine(); // 从输入中读取一行字符串
        String[] names = name.split("\\s+"); // 将字符串按照空格或多个空格进行分割,得到一个字符串数组
        HashMap<String, Integer> students = new HashMap<String, Integer>(); // 创建一个HashMap用于存储学生名字和出现次数

        // 使用foreach循环遍历names数组,以name为key,以其出现次数为value,将其存入students中
        for (String namestring : names) {
            // students.getOrDefault(namestring, 0)表示当HashMap students中没有该namestring时,返回0;若有则返回其value
            // 最后+1表示又被点到一次,将其放入students中
            students.put(namestring, students.getOrDefault(namestring, 0) + 1);
        }

        // 调用Collections类中的max()方法找到students.values()返回的集合中的最大值
        int max = Collections.max(students.values());

        List<String> maxname = new ArrayList<String>(); // 创建一个列表用于存储出现次数最多的学生名字

        // 使用foreach循环遍历students的键值对集合entrySet
        for (Map.Entry<String, Integer> entry : students.entrySet()) {
            if (entry.getValue() == max) {
                maxname.add(entry.getKey()); // 如果某个学生的出现次数等于最大值,将其名字添加到maxname列表中
            }
        }

        Iterator<String> iterator = maxname.iterator(); // 创建一个迭代器用于遍历maxname列表
        int j = 0;
        while (iterator.hasNext()) {
            if (j == 0) {
                System.out.print(iterator.next()); // 如果是第一个学生名字,直接输出
                j = 1;
            } else {
                System.out.print(" " + iterator.next()); // 如果不是第一个学生名字,在前面加上空格后输出
            }
        }

    }

}

为什么使用列表存储学生名字? 

1. 因为列表(ArrayList)是一个动态大小的数据结构,可以根据需要自动扩展或缩小。在这个代码中,我们无法提前知道有多少个学生名字会出现次数最多,所以使用列表可以方便地添加和删除元素。

2. 列表保持元素的插入顺序,可以按照添加的顺序遍历和访问元素。在这个代码中,我们需要按照学生名字的顺序输出结果,所以使用列表可以确保输出的顺序是正确的。

键值对(key-value pair)是啥?

Map.Entry是一个接口,用于表示Map中的键值对(key-value pair)。它是Map接口的内部接口,用于表示Map中的每个元素。Map.Entry接口提供了获取键和值的方法,以及一些其他操作。

在这个代码中,Map.Entry<String, Integer>表示一个具体的键值对,其中String表示键的类型,Integer表示值的类型。通过使用Map.Entry<String, Integer>,我们可以访问和操作这个键值对的键和值。注:为什么在<String, Integer>中使用Integer而不是int?因为Integer是一个类而不是基本数据类型int,泛型不支持基本数据类型,只能使用类作为类型参数。

例如,可以使用entry.getKey()方法获取键,使用entry.getValue()方法获取值。在这段代码中,我们使用entry.getKey()获取学生名字,使用entry.getValue()获取学生出现的次数。

需要注意的是,Map.Entry是一个接口,不能直接实例化。它通常是通过Map的entrySet()方法返回的Set集合来获取键值对的实例。

ps: 关于泛型(Generics),在答案中,可以将以下代码改为

 HashMap<String, Integer> students = new HashMap<String, Integer>();

如下

 HashMap<String, Integer> students = new HashMap<>();

后面的<>将自动匹配前面的泛型 。

以下是几种不同语言的解决方案: ### Java 解决方案 可以使用 `HashMap` 来记录每个出勤次数,最后找出出勤次数最多。 ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 用于存储每个出勤次数 HashMap<String, Integer> map = new HashMap<>(); String str = sc.nextLine(); String[] arr = str.split(" "); ArrayList<String> list = new ArrayList<>(); int max = 1; for (int i = 0; i < arr.length; i++) { if (!map.containsKey(arr[i])) { map.put(arr[i], 1); list.add(arr[i]); } else { map.replace(arr[i], map.get(arr[i]) + 1); if (map.get(arr[i]) > max) { max = map.get(arr[i]); list.clear(); list.add(arr[i]); } else if (map.get(arr[i]) == max) { list.add(arr[i]); } } } for (int i = 0; i < list.size(); i++) { if (i != list.size() - 1) { System.out.print(list.get(i) + " "); } else { System.out.print(list.get(i)); } } } } ``` 此代码通过 `HashMap` 统计每个出勤次数,同时使用 `ArrayList` 记录出勤次数最多。如果有多出勤次数相同且最多,将他们都记录在 `ArrayList` 中并输出 [^1]。 ### C 语言解决方案 ```c #include <stdio.h> #include <string.h> #define MAX_NAME_LENGTH 100 #define MAX_NAMES 500 int main() { char input[1000]; fgets(input, sizeof(input), stdin); // 去除换行符 input[strcspn(input, "\n")] = 0; char names[MAX_NAMES][MAX_NAME_LENGTH]; int counts[MAX_NAMES] = {0}; int nameCount = 0; // 分割输入字符串并统计每个名字的出现次数 char *token = strtok(input, " "); while (token != NULL) { int found = 0; for (int i = 0; i < nameCount; i++) { if (strcmp(names[i], token) == 0) { counts[i]++; found = 1; break; } } if (!found) { strcpy(names[nameCount], token); counts[nameCount] = 1; nameCount++; } token = strtok(NULL, " "); } int maxCount = 0; for (int i = 0; i < nameCount; i++) { if (counts[i] > maxCount) { maxCount = counts[i]; } } int first = 1; for (int i = 0; i < nameCount; i++) { if (counts[i] == maxCount) { if (!first) { printf(" "); } printf("%s", names[i]); first = 0; } } printf("\n"); return 0; } ``` 此 C 语言代码通过 `strtok` 函数分割输入字符串,统计每个名字的出现次数,最后找出出勤次数最多并输出 [^3]。 ### Python 解决方案 ```python # 获取输入 attendance = input().split() # 统计每个出勤次数 attendance_count = {} for person in attendance: if person in attendance_count: attendance_count[person] += 1 else: attendance_count[person] = 1 # 找出最大出勤次数 max_attendance = max(attendance_count.values()) # 找出出勤次数最多 most_attended = [person for person, count in attendance_count.items() if count == max_attendance] # 输出结果 print(" ".join(most_attended)) ``` Python 代码使用字典 `attendance_count` 统计每个出勤次数,然后找出最大出勤次数,最后找出出勤次数等于最大出勤次数的并输出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值