一、题目描述
根据访问日志统计接口的日活和月活。日志格式为
yyyy-mm-dd|clientIP|url|result
其中yyyy-mm-dd代表年月日,一个日志文件中时间跨度保证都在同一个月内,但不保证每行是按照日期顺序。
clientIP为合法的点分十进制ipv4地址(1.1.1.1和1.01.001.1视作同一IP地址)
url访问的地址,格式为/login.do,/query.html,,仅包含字母、英文句号.、斜杠/、和下划线_
result接口的访问结果,只有2种:success和fail
日活:统计当天有多少不同IP访问地址是/login.do且结果为success
月活:统计当月有多少不同IP访问地址是/login.do且结果为success。注意月活数量不是日活数量的简单累加!
输出规则
第一个是月活,第2~31代表当月第1到第31天的日活数
样例
输入
2025-01-01|192.168.218.218|/login.do|success
2025-01-01|192.168.218.218|/login.do|success
2025-01-01|192.168.210.210|/login.do|fail
2025-01-02|192.168.210.210|/login.do|success
2025-01-02|192.168.218.218|/login.do|success
输出
2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
二、算法实现
// 获取月活,日活
public static int[] getActiveUserNum(List<String> logs) {
// key存当天,value存放IP,自动去重
Map<Integer, Set<String>> activeIpMap = new HashMap<>();
// 月活
activeIpMap.put(0, new HashSet<>());
for (String log : logs) {
if (log.endsWith("fail") || !log.contains("login.do|success")) {
continue;
}
Integer day = Integer.valueOf(log.substring(8, 10));
String ip = getFormateIp(log);
if (!activeIpMap.containsKey(day)) {
activeIpMap.put(day, new HashSet<>());
}
// 日活
activeIpMap.get(day).add(ip);
// 月活
activeIpMap.get(0).add(ip);
}
int[] res = new int[32];
for (int i = 0; i < res.length; i++) {
if (!activeIpMap.containsKey(i)) {
continue;
}
res[i] = activeIpMap.get(i).size();
}
return res;
}
// 对IP地址格式化
private static String getFormateIp(String log) {
String[] infos = log.split("\\|");
String[] ipNums = infos[1].split("\\.");
String ip = "";
for (int i = 0; i < ipNums.length; i++) {
if (i == ipNums.length - 1) {
ip += Integer.valueOf(ipNums[i]);
} else {
ip += Integer.valueOf(ipNums[i]) + ".";
}
}
return ip;
}