題一:
開發一個簡單錯誤記錄功能小子產品,能夠記錄出錯的代碼所在的檔案名稱和行号。
處理:
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++;
}
}
}