一、题目
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
二、思路
(一)、使用map
(二)、使用辅助类
考察到:Map,稳定排序等。
注意输出格式,每个结果之间都有空格
三、代码
使用map
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 为了保证按照输入先后有序,使用LinkedHashMap
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
while (scanner.hasNext()) {
String path = scanner.next();
int id = path.lastIndexOf('\\');
String fileName = id == -1 ? path : path.substring(id + 1);
int line = scanner.nextInt();
// 统计频率
String key = fileName + " " + line;
// map.put(key, map.getOrDefault(key, 0) + 1);
if (map.containsKey(key)) {
map.put(key, map.get(key) + 1);
} else {
map.put(key, 1);
}
}
// 对记录进行排序
List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(map.entrySet());
list.sort(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
// 只输出前8条
int m = 0;
for (Map.Entry<String, Integer> mapping : list) {
if (m >= 8){
break;
}
String[] str = mapping.getKey().split(" ");
String fileName = str[0];
// 只需要输出16位
if (fileName.length() > 16) {
fileName = fileName.substring(fileName.length() - 16);
}
String n = str[1];
Integer count = mapping.getValue();
System.out.printf("%s %s %d%n", fileName, n, count);
m++;
}
}
}
辅助类
package Java7_6.OJ;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
class Record {
// 文件名
public String fileName;
// 错误所在代码行
public int row;
// 错误数目
public int errorNum = 1;
public Record(String fileName, int row) {
this.fileName = fileName;
this.row = row;
}
public void setErrorNum() {
this.errorNum++;
}
@Override
public boolean equals(Object another) {
if (another == null){
return false;
}
if (another instanceof Record){
Record anotherRecord = (Record) another;
return this.fileName.equals(anotherRecord.fileName) && this.row == anotherRecord.row;
}
return false;
}
}
public class Solution {
public static void main(String[] args) {
// 错误记录列表,必须定义在外边
List<Record> list = new LinkedList<>();
// 输入操作
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
// 输入文件路径
String filePath = scanner.next();
// 输入错误行数
int row = scanner.nextInt();
String[] strings = filePath.split("\\\\");
String fileName = strings[strings.length - 1];
Record newRecord = new Record(fileName, row);
// 如果错误列表中已经有了,就把错误次数加一 , 这里需要重写equals方法
if (list.contains(newRecord)){
int index = list.indexOf(newRecord);
list.get(index).setErrorNum();
}else{
list.add(newRecord);
}
}
// 逆序:由大到小
list.sort(new Comparator<Record>() {
@Override
public int compare(Record o1, Record o2) {
return o2.errorNum - o1.errorNum;
}
});
// 只输出前八个
int bound = Math.min(8, list.size());
for (int i = 0; i < bound; i++) {
// 如果文件名超过16个字符,则只输出后16个字符
String fN = list.get(i).fileName;
if (fN.length() > 16){
fN = fN.substring(fN.length()-16);
}
System.out.println(fN + " " + list.get(i).row + " " + list.get(i).errorNum);
}
}
}