题意整理。

  • 开发一个错误记录功能的小模块,能够记录出错的代码所在的文件名称和行号。
  • 输入字符串为“全路径名+空格+行号”的格式,输出字符串为“有效文件名+空格+行号+空格+出现次数”的格式。
  • 有如下处理规则:1.只记录出错的最后8条记录,如果有重复的,则计数加一;2.长度超过16的文件名称,只保留最后16个有效字符;3.只要有效字符相同,则视为相同的文件名;4.以第一次出错的时间为准。

方法一(模拟)

1.解题思路

  • 首先新建map,文件名+空格+行号作为键,对应的数量作为值。
  • 然后通过字符串分割,得到文件名,如果长度大于16,则只取最后有效16个字符。利用文件名和行号构造map的键。将对应的键放入map,如果出现过,则计数加1。(因为需要按时间先后,至多统计最后出错的8条记录,所以数据结构采用的LinkedHashMap,保证有序)
  • 最后遍历map,如果长度大于8,取最后8条记录,否则取所有的记录。

图解展示: alt

2.代码实现

import java.util.Scanner;
import java.util.LinkedHashMap;

public class Main{
    public static void main(String[] args){
        //标准输入
        Scanner sc=new Scanner(System.in);
        //新建map,文件名+空格+行号作为键,对应的数量作为值
        LinkedHashMap<String,Integer> map=new LinkedHashMap<>();
        while(sc.hasNext()){
            //输入字符串
            String s=sc.next();
            //行号
            int num=sc.nextInt();
            //分割路径
            String[] arr=s.split("\\\\");
            //得到文件名
            String strarr=arr[arr.length-1];
            //如果大于16,则只取最后有效16个字符
            if(strarr.length()>16){
                strarr=strarr.substring(strarr.length()-16);
            }
            //构造键
            String key=strarr+" "+num;
            //将对应数据放入map
            if(!map.containsKey(key)){
                map.put(key,1);
            }
            else{
                map.put(key,map.get(key)+1);
            }            
        }
        int n=map.size();
        for(String k:map.keySet()){
            //至多取最后8条记录
            if(n<=8){
                System.out.println(k+" "+map.get(k));
            }
            n--;
        }
    }
}

3.复杂度分析

  • 时间复杂度:假设错误记录的数量为n,需要遍历所有的错误记录,所以时间复杂度为O(n)O(n)
  • 空间复杂度:最坏情况下,需要额外大小为nn的map,所以空间复杂度为O(n)O(n)

方法二(利用io流)

1.解题思路

思路和方法一基本一致,不同的是通过io流操作来处理输入的数据。对于构造map键的方式,只需预先计算最后一个空格和"\"出现的位置(分别记为index1和index2),然后判断文件名长度,如果长度大于16,则从index1-16处截取输入字符串,作为键;如果长度小于等于16,则从index2+1处截取输入字符串,作为键。

2.代码实现

import java.util.LinkedHashMap;
import java.io.*;

public class Main{
    public static void main(String[] args) throws Exception{
        //标准输入
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        //新建map,文件名+空格+行号作为键,对应的数量作为值
        LinkedHashMap<String,Integer> map=new LinkedHashMap<>();
        //输入字符串
        String s;
        while((s=br.readLine())!=null){
            
            //最后一个空格出现的位置
            int index1=s.lastIndexOf(" ");
            //最后一个"\\"出现的位置
            int index2=s.lastIndexOf("\\");
            //构造文件名+空格+行号
            String strarr="";
            //如果大于16,则只取最后有效16个字符
            if(index1-index2>16){
                strarr=s.substring(index1-16);
            }
            //否则,从文件名第一个字符的位置开始截取
            else{
                strarr=s.substring(index2+1);
            }
            //构造键
            String key=strarr;
            //将对应数据放入map
            if(!map.containsKey(key)){
                map.put(key,1);
            }
            else{
                map.put(key,map.get(key)+1);
            }            
        }
        int n=map.size();
        for(String k:map.keySet()){
            //至多取最后8条记录
            if(n<=8){
                System.out.println(k+" "+map.get(k));
            }
            n--;
        }
    }
}

3.复杂度分析

  • 时间复杂度:假设错误记录的数量为n,需要遍历所有的错误记录,所以时间复杂度为O(n)O(n)
  • 空间复杂度:最坏情况下,需要额外大小为nn的map,所以空间复杂度为O(n)O(n)