图解算法——简单错误记录
1、题目描述
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1> 记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并);
2> 超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并);
3> 输入的文件可能带路径,记录文件名称不能带路径。
2、示例
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。文件路径为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
解释:
fpgadrive.c是文件名字,后面的1 表示出现了一次。
3、解题思路
需要注意的点有如下几个:
1> 利用String的split方法分割反斜杠(\),split()里是正则表达式,如要以反斜杠分割,需要是str.split("\\\\"),如要是以空格分割,是str.split("\\s");
2> 我们知道要用map,但是用有序的 linkedhashMap 还是 无序的 hashmap,答案肯定是有序的;
3> 选好了数据结构,那么map中的key 和 value分别是什么呢?一开始我选的 key 是文件名(xxxxxxx.c),value 是另一个submap<String, Integer>,submap中的subkey 是行数,subvalue是错误的次数。但是后来发现不对,应当以文件名和空格和行数作为 map 的key ,次数作为map 的value,愿意主要有两个:一是结构更为简单,没有嵌套的map;二是题目中说了只要文件名和行数一样,就按照一样的叠加处理,不管他路径如何。既然题目中都这样说了,我们干嘛还要将文件名和行数拆开复杂化呢?你说是吧?
代码如下:
import java.util.*; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); //因为要求是相同情况下按输入顺序输出,故这里就不能用hashmap了,应该用有序的linkedhashmap; Map<String,Integer> map = new LinkedHashMap<String,Integer>(); //Map<String,Integer> map = new HashMap<String,Integer>(); while(sc.hasNext()){ //获得文件名和空格和行数,三者组成的字符串,作为map中的key; String[] strs = sc.nextLine().split("\\\\"); String filename = strs[strs.length - 1]; //判断是否包含该文件名和行数的key if(!map.containsKey(filename)){ map.put(filename,1); }else{ map.put(filename,map.get(filename)+1); } } //为了排序输出,故将map中的Entry<k,v>转存入list列表中,并利用容器类Collections的sort() 的方法进行排序; List<Map.Entry<String,Integer>> list = new ArrayList<>(map.entrySet()); Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){ @Override public int compare(Map.Entry<String,Integer> o1, Map.Entry<String,Integer> o2){ return o2.getValue().compareTo(o1.getValue()); } }); //最多输出八次 for(int i = 0; i<8; i++){ String[] strs = list.get(i).getKey().split("\\s"); //文件名长度输出最后16位 if(strs[0].length() > 16){ strs[0] = strs[0].substring(strs[0].length()-16); } System.out.println(strs[0]+" "+strs[1]+" "+list.get(i).getValue()); } sc.close(); } }
Over..........