题一:
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1、 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:
示例1
输入
E:\V1R2\product\fpgadrive.c 1325
输出
fpgadrive.c 1325 1
净文件名指的是去掉前面的路径所得
比如C:\test\abc.txt净文件名就是abc.txt
题目说的是净文件名和行号完全一致,也就是说我们不关注文件的路径,只关注后边的净文件名
比如C:\test\abc.txt20、D:\test\abc.txt20这两个文件的净文件名都是abc.txt,行号都是20,那么这两条错误记录就是相同的
思路:由于题目说文件可能带路径,而我们最终比的也是净文件名和行号,所以我们首先要做的就是判断所给文件名是否带路径,
在提取出净文件名之后,由于要记录错误记录的条数,所以我们用HashMap存储,又最后要按顺序输出,所以使用的是LinkedHashMap
然后我们可以将净文件名和行号当做一个整体作为key,然后记录其value
最后在输出最多8条记录的时候,需要注意的是输出的是后8条记录
public class SimpleErrorRecord1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<String, Integer> map = new LinkedHashMap<>();
while (scanner.hasNext()) {
String str = scanner.nextLine();
int index = str.lastIndexOf("\\"); //看是否存在\
if (index != -1) { //如果存在,表明不是净文件名,需要从\后边的字符开始提取
str = str.substring(index + 1); //净文件名+" "+行号
}
if (!map.containsKey(str)) {
map.put(str, 1);
} else {
map.put(str, map.get(str) + 1);
}
}
Set<String> set = map.keySet();
int count = 0;
for (String tmp : set) {
count++;
if (count > (set.size() - 8)) { //输出的是后8条记录
String[] s = tmp.split(" "); //按空格分割key
String name = s[0]; //取得净文件名
int len = name.length();
if (len > 16) { //如果净文件名长度大于16,只取后16位
name = name.substring(len - 16);
}
int line = Integer.parseInt(s[1]); //取得行号
int number = map.get(tmp); //取得此错误记录的条数
System.out.println(name + " " + line + " " + number);
}
}
}
}
题二:
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325
输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
示例1
输入
E:\V1R2\product\fpgadrive.c 1325
输出
fpgadrive.c 1325 1
对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并):这句话的意思也是只要净文件名和行号相同就算作是相同的错误记录
这道题大致跟上一道简单错误记录题差不多。细微的区别就是最后输出的时候需要根据数目降序排序,所以我们就需要在输出前先对整个map进行一次降序排序
而且需要注意的是,如果超过8条记录,我们输出的是前8条【上一道输出的是后8条】
public class SimpleErrorRecord2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Map<String, Integer> map = new LinkedHashMap<>(); //保证按插入时的顺序存放元素
while (scanner.hasNext()) {
String str = scanner.next(); //可能带路径的文件名
int n = scanner.nextInt(); //行号
int index = str.lastIndexOf("\\"); //判断文件是否带路径,如果找到了最后一个\,表示此文件带路径,取出最后一个\后边的内容->文件名;否则此文件本身就是一个文件名
String name = index == -1 ? str : str.substring(index + 1);
String key = name + " " + String.valueOf(n);
if (!map.containsKey(key)) { //把文件名和行号共同作为key【文件名和行号中间以空格隔开】
map.put(key, 1);
} else {
map.put(key, map.get(key) + 1);
}
}
List<Map.Entry<String, Integer>> list = new LinkedList<>(map.entrySet()); //将map集合变成list,方便对map的value进行排序
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() { //传入一个降序比较器
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o1.getValue() > o2.getValue() ? -1 : o1.getValue().equals(o2.getValue()) ? 0 : 1;
}
});
int m = 0;
for (Map.Entry<String, Integer> mx : list) {
if (m >= 8) { //最多输出8条 按顺序
break;
}
String[] k = mx.getKey().split(" "); //取出key值,并按空格分割
String fName = k[0]; //取出文件名
if (fName.length() > 16) { //如果文件名长度大于16,只取后16位
fName = fName.substring(fName.length() - 16);
}
String line = k[1]; //取出行号
int count = mx.getValue(); //取出错误数
System.out.println(fName + " " + line + " " + count);
m++;
}
}
}