import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
/*
记录出错的代码所在的文件名称和行号。
最多8条,循环记录,只输出最后八条错误记录。
超过16个字符的文件名称,只记录文件的最后有效16个字符
循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准
相同的错误记录只记录一条,但是错误记数 增加。
最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是“相同”的错误记录
哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
* */
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
//定义一个Hashmap链表,key存储 错误信息的16位+“ ”+行号,value存储 错误记录数量(ELNum)。
LinkedHashMap<String,Integer> LHMapEL = new LinkedHashMap<>();
//LinkedHashMap存储不重复且有序(HashMap本身无序,而链表的HashMap有序,且是按照存储顺序记录)的键值对。
while (sc.hasNextLine()){
StringBuilder errorLogging = new StringBuilder(sc.nextLine()); //一行错误记录,有文件名和行号
String strEL = EL(errorLogging);
Integer ELNum = 0;//错误记录数量
if(LHMapEL.containsKey(strEL)){
//如果有包含这个记录的键key,则修改ELNum值,然后覆盖这个值value(键相同,值覆盖)。
ELNum = LHMapEL.get(strEL) + 1;
LHMapEL.put(strEL,ELNum);
}else {
ELNum += 1;
LHMapEL.put(strEL,ELNum);
}
}
int startIndex = 0;//只输出最后8个记录的 起始位置
int counter = 0;//遍历时加一个计数器counter
if(LHMapEL.size() > 8){
//如果size大于8,输出后8个(例如:27个,27-8=19,从第19个开始输出到26为止,作为最后8个。)
startIndex = LHMapEL.size() - 8;
for(String c : LHMapEL.keySet()){
if(counter < startIndex){//按例27个,则小于19的都跳过,不输出
counter++;
continue;
}else {
System.out.println(c+ " " + LHMapEL.get(c));
counter++;
}
}
}else {
//如果size小于等于8,全部输出
for(String c : LHMapEL.keySet()){
System.out.println(c+ " " + LHMapEL.get(c));
counter++;
}
}
}
public static String EL(StringBuilder errorLogging){
int Index = errorLogging.lastIndexOf("\\")+1;//最后一个斜杠的位置
//保留最后一个斜杠的位置后面的一串字符,作为 错误记录 文件名和行号 有效信息。
String strEL = errorLogging.substring(Index, errorLogging.length());
String[] str = strEL.split(" ");//分成文件名和行号
//超过16个字符的文件名称,只记录文件的最后有效16个字符
if(str[0].length()>16){
strEL = str[0].substring(str[0].length()-16)+" "+str[1];
}else {
strEL = strEL;
}
return strEL;
}
}