在现代企业管理中,员工培训和学习活动的参与度是衡量员工积极性的重要指标。很多公司会组织新员工进行每日打卡学习活动,并希望通过数据分析找出表现最积极的员工。本文将详细介绍如何使用Java实现一个员工打卡统计系统,找出打卡次数最多的TOP5员工。
我们需要解决的问题可以分解为以下几个部分:
我们使用HashMap
来存储员工打卡记录,键是员工ID,值是一个包含两个元素的数组:
javaMap<Integer, int[]> employeeRecords = new HashMap<>();
其中:
int[0]
存储打卡次数int[1]
存储首次打卡日期(0-29表示30天)java// 读取30天的打卡数据
for (int day = 0; day < 30; day++) {
String[] idsStr = scanner.nextLine().split(" ");
for (String idStr : idsStr) {
int id = Integer.parseInt(idStr);
if (!employeeRecords.containsKey(id)) {
// 新员工:打卡次数=1,首次打卡日期=当前day
employeeRecords.put(id, new int[]{1, day});
} else {
// 已有员工:打卡次数+1,首次打卡日期不变
int[] record = employeeRecords.get(id);
record[0]++;
}
}
}
排序规则是本题的核心难点,我们需要实现三级排序:
javaCollections.sort(entries, new Comparator<Map.Entry<Integer, int[]>>() {
@Override
public int compare(Map.Entry<Integer, int[]> a, Map.Entry<Integer, int[]> b) {
int[] recordA = a.getValue();
int[] recordB = b.getValue();
// 1. 比较打卡次数(降序)
if (recordA[0] != recordB[0]) {
return Integer.compare(recordB[0], recordA[0]);
}
// 2. 比较首次打卡日期(升序)
else if (recordA[1] != recordB[1]) {
return Integer.compare(recordA[1], recordB[1]);
}
// 3. 比较员工ID(升序)
else {
return Integer.compare(a.getKey(), b.getKey());
}
}
});
javaimport java.util.*;
public class EmployeeAttendance {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取员工数量N
int N = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
// 读取30天的打卡员工数量(题目要求但实际不需要使用)
scanner.nextLine();
// 创建员工打卡记录:员工ID -> [打卡次数, 首次打卡日期]
Map<Integer, int[]> employeeRecords = new HashMap<>();
// 读取30天的打卡数据
for (int day = 0; day < 30; day++) {
String[] idsStr = scanner.nextLine().split(" ");
for (String idStr : idsStr) {
int id = Integer.parseInt(idStr);
if (!employeeRecords.containsKey(id)) {
// 新员工:打卡次数=1,首次打卡日期=当前day
employeeRecords.put(id, new int[]{1, day});
} else {
// 已有员工:打卡次数+1,首次打卡日期不变
int[] record = employeeRecords.get(id);
record[0]++;
}
}
}
// 转换为List以便排序
List<Map.Entry<Integer, int[]>> entries = new ArrayList<>(employeeRecords.entrySet());
// 自定义排序
Collections.sort(entries, new Comparator<Map.Entry<Integer, int[]>>() {
@Override
public int compare(Map.Entry<Integer, int[]> a, Map.Entry<Integer, int[]> b) {
int[] recordA = a.getValue();
int[] recordB = b.getValue();
// 1. 比较打卡次数(降序)
if (recordA[0] != recordB[0]) {
return Integer.compare(recordB[0], recordA[0]);
}
// 2. 比较首次打卡日期(升序)
else if (recordA[1] != recordB[1]) {
return Integer.compare(recordA[1], recordB[1]);
}
// 3. 比较员工ID(升序)
else {
return Integer.compare(a.getKey(), b.getKey());
}
}
});
// 输出TOP5(或更少)
int count = Math.min(5, entries.size());
for (int i = 0; i < count; i++) {
if (i > 0) {
System.out.print(" ");
}
System.out.print(entries.get(i).getKey());
}
}
}
这个基础算法可以扩展应用到许多实际场景:
通过这个案例,我们学习了:
这种类型的问题在编程面试中也经常出现,掌握这类问题的解决方法对提升编程能力很有帮助。
欢迎在评论区分享你的想法和解决方案!