首页 > 试题广场 >

简单错误记录

[编程题]简单错误记录
  • 热度指数:362296 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
\hspace{15pt}在本题中,我们需要处理文件报错信息,其由出错文件的文件路径和错误行号组成。

\hspace{15pt}文件路径的前三个字母为大写字母 \texttt{A-Z} 、冒号 \texttt{ 和反斜杠 \texttt{ ,代表盘符;随后是若干由小写字母构成的字符串,代表文件夹名,彼此使用单个反斜杠间隔。路径的最后一个反斜杠后是文件名。
\hspace{15pt}我们只在乎文件名(即去掉除了文件名以外的全部信息),且至多保留文件名的最后 16 个字符。

\hspace{15pt}随后,我们需要统计相同的报错信息:
\hspace{23pt}\bullet\,如果两条报错信息保留后 16 个字符后的文件名相同,且行号相同,则视为同一个报错;

\hspace{15pt}相同的报错信息以第一次出现的时间为准,至多输出最后 8 条记录。

输入描述:
\hspace{15pt}本题将会给出 1 \leqq T \leqq 100 条报错信息,确切数字未知,您需要一直读入直到文件结尾;您也可以参考 牛客网在线判题系统使用帮助 获得更多的使用帮助。每条报错信息描述如下:

\hspace{15pt}在一行上先输入一个长度为 1 \leqq {\rm length}(x) \leqq 100 的字符串 x 代表文件路径;随后,在同一行输入一个整数 y \left( 1 \leqq y \leqq 1000 \right) 代表行号。
\hspace{15pt}文件路径的格式如题干所述,保证文件名不为空。


输出描述:
\hspace{15pt}至多八行,每行先输出一个长度为 1 \leqq {\rm length}(s) \leqq 16 的字符串 s ,代表文件名;随后,在同一行输出错误行号、报错次数。
示例1

输入

D:\oblemsinnowcoder 12
D:\nowcoderproblemsinnowcoder 12
D:\nowcoder\problemsinnowcoder 13
D:\oj\problemsinnowcoder 13

输出

oblemsinnowcoder 12 2
oblemsinnowcoder 13 2

说明

\hspace{15pt}在这个样例中,这四条报错信息去除文件路径后,由于文件名长度均超过 16 个字符,故我们只保留最后 16 个字符,得到的文件名均为 \texttt{ 。所以,我们将它们看作同一个文件,按照报错行号划分即可。
示例2

输入

A:\aa 1
B:\b 1
C:\c 1
D:\d 1
E:\e 1
F:\f 1
G:\g 1
H:\h 1
I:\i 1
A:\aa 1

输出

b 1 1
c 1 1
d 1 1
e 1 1
f 1 1
g 1 1
h 1 1
i 1 1

说明

\hspace{15pt}在这个样例中,第一、十条报错信息完全相同,但是我们以其第一次出现的顺序为准,在输出最后 8 条记录时,不包含这一报错。
示例3

输入

D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645

输出

rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        List<String> errList = new ArrayList<>();
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String inputStr = in.nextLine().trim();//去除空行
            //空行则返回
            if (inputStr .isEmpty()) return;
            if (inputStr.equals("END")) {
                //检测到输入“END”时,退出循环
                break;
            }
            String[] arr1 = inputStr.split(" ");
            //长度不为2表示输入有问题,退出
            if (arr1.length != 2) return;
            //处理文件路径
            String str1 = arr1[0];
            if (str1.length() < 3 ) return;
            char c1 = str1.charAt(0);
            char c2 = str1.charAt(1);
            char c3 = str1.charAt(2);
            if (c1 < 'A' || c1 > 'Z' || c2 != ':' || c3 != '\\') {//非正常格式,退出
                return;
            }
            String[] addressArr = str1.split("\\\\");
            if (addressArr.length < 2 ) {//非正常格式,退出
                return;
            }
            String address;
            String addressTemp = addressArr[addressArr.length - 1];
            if (addressTemp.length() > 16) {
                //截取地址的后16位
                address = addressTemp.substring(addressTemp.length() - 16, addressTemp.length());
            } else {
                address = addressTemp;
            }
            //处理行数
            String str2 = arr1[1];
            //为空退出
            if (str2.length() < 0) return;
            //不是数字组成,退出
            for (char c : str2.toCharArray()) {
                if (!Character.isDigit(c)) {
                    return;
                }
            }
            //获取行号
            String line = str2.trim();
            List<String> tempList = new ArrayList<>();
            String errRecord = address + " " + line;
            errList = addRecord(errRecord, errList);
        }
        //如果errList的长度>8 ,则从倒数第8个开始输出
        int i = 0;
        if (errList.size() > 8 ) {
            i = errList.size() - 8;
        }
        for (; i < errList.size(); i ++) {
            System.out.println(errList.get(i));
        }
        in.close();
    }

    //对于重复的文件名和行数,++
    public static List<String> addRecord(String str, List<String> list) {
        String[] arr = str.split(" ");
        if (list.size() == 0) { //为空时,直接加入这行,并且计数为1
            str = str + " 1";
            list.add(str);
            return list;
        }
        for (int i = 0; i < list.size(); i ++) {
            String[] arr1 = list.get(i).split(" ");
            //取出list中的计数部分,转化为数字
            String count = arr1[2];
            int n = Integer.parseInt(count);
            //将输入的 字符串分割成可以判断的数组,进行对比判断
            String[] arr2 = str.split(" ");
            if ( arr1[0].equals(arr2[0]) && arr1[1].equals(arr2[1])) {
                //对比address和line是否已经存在,如果存在,则在计数上+1 ,并且替换原有list位置中的数据
                n++;
                str = str + " " + n + "";
                list.set(i, str);
                return list;
            } else {
                if (i == list.size() - 1) {
                    //不存在则直接+1
                    str = str + " 1";
                    list.add(str);
                    return list;
                }
            }
        }
        return list;
    }
}

发表于 2025-06-22 19:01:35 回复(0)
import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
public class Main {
    public static void main(String[] args) {
        HashMap<String,Integer> map=new HashMap<>();
        ArrayList<String[]> list=new ArrayList<>();
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) { 
            String[] str=in.nextLine().split(" ");
            String s=str[0].split("\\\\")[str[0].split("\\\\").length-1];
            if(s.length()>16){
                s=s.substring(s.length()-16,s.length());
            }
            if(map.containsKey(s+str[1])){
                map.put(s+str[1],map.get(s+str[1])+1);
            }else{
                map.put(s+str[1],1);
                String[] s1=new String[2];
                s1[0]=s;
                s1[1]=str[1];
                list.add(s1);
            }
        }
        int i=0;
        if(list.size()>8){
            i=list.size()-8;
        }
        for(;i<list.size();i++){
            System.out.println(list.get(i)[0]+" "+list.get(i)[1]+" "+map.get(list.get(i)[0]+list.get(i)[1]));
        }
        in.close();
    }
}

发表于 2025-04-01 20:37:08 回复(0)
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Scanner;

public class Main {
    /**
     * 主函数,用于处理输入的文件路径和行号,并统计每个文件路径和行号的出现次数
     *
     * @param args 命令行参数
     * @throws IOException 如果输入输出操作失败
     */
    public static void main(String[] args) throws IOException {
        // 创建一个Scanner对象,用于读取标准输入
        Scanner sc = new Scanner(System.in);
        // 创建一个LinkedHashMap对象,用于存储文件路径和行号的出现次数
        // LinkedHashMap保证了插入顺序,便于后续输出最后八个记录
        HashMap<String, Integer> map = new LinkedHashMap<String, Integer>();

        // 循环读取输入,直到没有更多输入
        while (sc.hasNext()) {
            // 读取一个字符串,表示文件路径
            String str = sc.next();
            // 读取一个整数,表示行号
            int LineNum = sc.nextInt();

            // 根据反斜杠分割文件路径,得到路径的各个部分
            String[] split = str.split("\\\\");
            // 获取路径的最后一部分,即文件名
            String FileName = split[split.length - 1];

            // 如果文件名长度超过16个字符,只保留最后16个字符
            if (FileName.length() > 16)
                FileName = FileName.substring(FileName.length() - 16);

            // 构建一个键,由文件名和行号组成
            String key = FileName + " " + LineNum;

            // 如果键已经存在于map中,增加其对应的值(出现次数)
            if (map.containsKey(key))
                map.put(key, map.get(key) + 1);
            else {
                // 如果键不存在,将其添加到map中,并设置初始值为1
                map.put(key, 1);
            }
        }

        // 用于计数,记录已经输出的记录数
        int count = 0;
        // 遍历map的键集合
        for (String string : map.keySet()) {
            count++;
            // 如果已经输出的记录数大于总记录数减去8,即输出最后八个记录
            if (count > (map.keySet().size() - 8))
                // 输出键和对应的值(出现次数)
                System.out.println(string + " " + map.get(string));
        }
    }
}

发表于 2025-02-12 17:04:10 回复(0)
用链表记录顺序,用Map记录是否第一次出现
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        LinkedList<String> names = new LinkedList<>(); //保存顺序
        HashMap<String, Integer> map  = new HashMap<>(); //保存次数
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String s = in.next();
            int col = in.nextInt();
            String n = getName(s) + " " + col;
            //      System.out.println(n+"--------------------");
            if (!map.containsKey(n)) {
                names.add(n);
                map.put(n, 1);
            } else {
                col = map.get(n) + 1;
                map.put(n, col);
            }
        }
        if (names.size() <= 8) {
            for (String name : names) {
                int num = map.get(name);
                System.out.println(name + " " + num);
            }
        }else{
        for (int i = names.size()-8; i < names.size() ; i++) {
            System.out.println(names.get(i)+" "+map.get(names.get(i)));
        }
        }
    }

    public static String getName(String file) {
        String[] split = file.split("\\\\");
        String name = split[split.length - 1];
        if (name.length() <= 16)
            return name;
        return name.substring(name.length() - 16);
    }
}


发表于 2025-02-11 20:57:06 回复(0)
题目没有说明什么时候中断输入
发表于 2024-12-20 15:40:15 回复(0)

0 题目分析

存放结果的数据结构只能有8个元素,循环记录,不需要的要被自动挤掉。
也就是说久远的错误要自动被挤掉(当前错误要加入时,发现已经满了,那么最先加入的就要删去)
不久远的错误要累加次数(当前错误要加入时,如果这个错误首次出现的位置距离现在并不远(实际这个距离就是8)那我们就要更新次数。)

1 考虑到以下限制,选择使用单链表

①是循环记录,结果只有8个
②过于久远的记录(要记录时,发现这个记录首次出现位置距离当前位置已经超过了8)会被删除(头部删除)
③新纪录需要插入到尾部保证顺序
④不那么久远的记录(要记录时,发现这个记录首次出现位置距离当前位置还没有超过8)需要更新。
根据以上分析,会涉及频繁的头部删除,尾部添加,甚至是内部某处的更新。那么我们毫不犹豫的选择单链表即可。
可以自写一个节点类,含两个成员属性,一个是文件名和行号,一个是出现次数。在类内部编写获取链表大小方法,尾插方法,头部删除方法,内部更新方法。
class ErrorRecordNode {
    String fileNameAndLineNumber; // 文件名和行号
    int count; // 错误次数
    ErrorRecordNode next; // 下一个节点

    // 构造方法
    public ErrorRecordNode(String fileNameAndLineNumber, int count) {
        this.fileNameAndLineNumber = fileNameAndLineNumber;
        this.count = count;
        this.next = null; // 默认指向null
    }

    // 获取链表节点个数
    public static int getNodeCount(ErrorRecordNode head) {
        int count = 0; // 节点计数器
        ErrorRecordNode current = head; // 当前节点指针
        while (current != null) {
            count++; // 计数加一
            current = current.next; // 移动到下一个节点
        }
        return count;
    }

    // 尾插法
    public static ErrorRecordNode appendTail(ErrorRecordNode head, String fileNameAndLineNumber, int count) {
        ErrorRecordNode newNode = new ErrorRecordNode(fileNameAndLineNumber, count);
        if (head == null) {
            // 如果链表为空,则新节点直接作为头节点返回
            return newNode;
        }
        ErrorRecordNode current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = newNode; // 将新节点添加到链表尾部
        return head;
    }

    // 去除头节点
    public static ErrorRecordNode removeHead(ErrorRecordNode head) {
        if (head == null) {
            return null; // 链表为空,直接返回null
        }
        return head.next; // 返回原头节点的下一节点
    }

    // 更新 count 方法
    public static void updateCount(ErrorRecordNode head, String fileNameAndLineNumber) {
        ErrorRecordNode current = head;
        while (current != null) {
            if (current.fileNameAndLineNumber.equals(fileNameAndLineNumber)) {
                current.count++; // 找到匹配节点,count加一
                return; // 更新后返回,不再遍历剩余节点
            }
            current = current.next; // 否则继续遍历下一个节点
        }
        System.out.println("未找到匹配的节点: " + fileNameAndLineNumber);
    }

    // 覆盖 toString 方法,用于链表的可视化
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        ErrorRecordNode current = this;
        while (current != null) {
            sb.append("{")
                    .append("fileNameAndLineNumber='").append(current.fileNameAndLineNumber).append("'")
                    .append(", count=").append(current.count)
                    .append("} -> ");
            current = current.next;
        }
        sb.append("null"); // 表示链表的结尾
        return sb.toString();
    }

    // 测试用例
    public static void main(String[] args) {
        // 创建链表头节点
        ErrorRecordNode head = new ErrorRecordNode("file1.cpp:10", 1);
        // 尾插几个节点
        head = appendTail(head, "file2.cpp:20", 2);
        head = appendTail(head, "file3.cpp:30", 3);

        System.out.println("链表内容:");
        System.out.println(head);

        // 去除头节点
        head = removeHead(head);
        System.out.println("去除头节点后:");
        System.out.println(head);

        // 再次去除头节点
        head = removeHead(head);
        System.out.println("再次去除头节点后:");
        System.out.println(head);
    }
}

2 如何实现久远错误的剥离?

只需要在新增错误的时候,检查链表是不是已经满了,满了就说明头结点这个错误已经过于久远了,删除头部,并尾部插入新错误即可。

3 如何判断当前错误是否要加入?

首先要动态记录位置,每来一个记录,位置就应该要加一
每次错误来了,我们都去存map,如果是第一次加入,就记录他的首次出现位置,然后直接加入结果集(加入前要判断是否需要挤掉头部)
如果发现map里面已经有了,那么就检查当前位置和首次位置的差距,差的过远(current-first>7)就不管他了,他已经自动被挤掉了,否则就去内部更新

总结:

差的远了就不管   差的不远就更新   首次发现就直接加入,并在必要时挤掉头部

4 完整代码

import java.util.HashMap;
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int location = 1;
        HashMap<String, Integer> firstLocationMap = new HashMap<>();
        ErrorRecordNode head = null;
        while (in.hasNextLine()) {
            String s = in.nextLine();

            if (s.equals("end")) {
                break;
            }

            String[] split = s.split("\\\\");
            String fileNameAndLineNumber = split[split.length - 1];
            
            String[] fileNameAndLineNumberArr = fileNameAndLineNumber.split(" ");
            String fileName = fileNameAndLineNumberArr[0];
            if (fileName.length() > 16) {
                //文件名大于16位的保留后16位
                fileName = fileName.substring(fileName.length() - 16);
                fileNameAndLineNumber= fileName + " " + fileNameAndLineNumberArr[1];
            }
            //检查这个文件和行数 首次出现的位置
            //如果没有key 表示第一次出现 直接加入
            if (!firstLocationMap.containsKey(fileNameAndLineNumber)) {
                firstLocationMap.put(fileNameAndLineNumber, location);
                //如果是第一次加入,一定会存入结果,且次数是1
                //但是还要考虑链表是不是已经满了 , 满8个就去掉头节点
                if (ErrorRecordNode.getNodeCount(head) == 8) {
                    head = ErrorRecordNode.removeHead(head);
                }
                //第一次加入,一定会存入结果,且次数是1
                head = ErrorRecordNode.appendTail(head, fileNameAndLineNumber, 1);
            } else {
                //如果这个文件和行数已经出现过,那么检查一下首次位置在哪里
                int firstLocation = firstLocationMap.get(fileNameAndLineNumber);

                //如果当前位置 - 首次出现位置 大于 7 说明这个错误已经过于久远了不能存入结果 比如 当前位置是9 首次出现位置是1 相减得到8 1到9是九个错误了 第一个错误如果再犯就不能再加入了
                //所以如果小于等于7 那么说明这个错误还不是很久远 那么就加入结果 更新其count
                if (location - firstLocation<=7) {
                    ErrorRecordNode.updateCount(head, fileNameAndLineNumber);
                }
            }
            location++;

        }
        while (head != null) {
            System.out.println(head.fileNameAndLineNumber + " " + head.count);
            head = head.next;
        }
    }


}

class ErrorRecordNode {
    String fileNameAndLineNumber; // 文件名和行号
    int count; // 错误次数
    ErrorRecordNode next; // 下一个节点

    // 构造方法
    public ErrorRecordNode(String fileNameAndLineNumber, int count) {
        this.fileNameAndLineNumber = fileNameAndLineNumber;
        this.count = count;
        this.next = null; // 默认指向null
    }

    // 获取链表节点个数
    public static int getNodeCount(ErrorRecordNode head) {
        int count = 0; // 节点计数器
        ErrorRecordNode current = head; // 当前节点指针
        while (current != null) {
            count++; // 计数加一
            current = current.next; // 移动到下一个节点
        }
        return count;
    }

    // 尾插法
    public static ErrorRecordNode appendTail(ErrorRecordNode head, String fileNameAndLineNumber, int count) {
        ErrorRecordNode newNode = new ErrorRecordNode(fileNameAndLineNumber, count);
        if (head == null) {
            // 如果链表为空,则新节点直接作为头节点返回
            return newNode;
        }
        ErrorRecordNode current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = newNode; // 将新节点添加到链表尾部
        return head;
    }

    // 去除头节点
    public static ErrorRecordNode removeHead(ErrorRecordNode head) {
        if (head == null) {
            return null; // 链表为空,直接返回null
        }
        return head.next; // 返回原头节点的下一节点
    }

    // 更新 count 方法
    public static void updateCount(ErrorRecordNode head, String fileNameAndLineNumber) {
        ErrorRecordNode current = head;
        while (current != null) {
            if (current.fileNameAndLineNumber.equals(fileNameAndLineNumber)) {
                current.count++; // 找到匹配节点,count加一
                return; // 更新后返回,不再遍历剩余节点
            }
            current = current.next; // 否则继续遍历下一个节点
        }
        System.out.println("未找到匹配的节点: " + fileNameAndLineNumber);
    }

    // 覆盖 toString 方法,用于链表的可视化
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        ErrorRecordNode current = this;
        while (current != null) {
            sb.append("{")
                    .append("fileNameAndLineNumber='").append(current.fileNameAndLineNumber).append("'")
                    .append(", count=").append(current.count)
                    .append("} -> ");
            current = current.next;
        }
        sb.append("null"); // 表示链表的结尾
        return sb.toString();
    }

    // 测试用例
    public static void main(String[] args) {
        // 创建链表头节点
        ErrorRecordNode head = new ErrorRecordNode("file1.cpp:10", 1);
        // 尾插几个节点
        head = appendTail(head, "file2.cpp:20", 2);
        head = appendTail(head, "file3.cpp:30", 3);

        System.out.println("链表内容:");
        System.out.println(head);

        // 去除头节点
        head = removeHead(head);
        System.out.println("去除头节点后:");
        System.out.println(head);

        // 再次去除头节点
        head = removeHead(head);
        System.out.println("再次去除头节点后:");
        System.out.println(head);
    }
}



发表于 2024-11-17 01:45:22 回复(0)
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Map<String, Integer> map = new LinkedHashMap<>();
        while (sc.hasNext()) {
            String s = sc.next();
            int line = sc.nextInt();
            String[] strings = s.split("\\\\");
            String fileName = strings[strings.length - 1];
            if (fileName.length() > 16) {
                fileName = fileName.substring(fileName.length() - 16);
            }
            fileName = fileName + " " + line;
            map.put(fileName, map.getOrDefault(fileName, 0) + 1);
        }
        int i = 0;
        for (String key : map.keySet()) {
            if (i >= map.size() - 8) {
                System.out.println(key + " " + map.get(key));
            }
            i++;
        }
        sc.close();
    }

}

发表于 2024-11-02 10:42:34 回复(0)
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        LinkedHashSet<String> myHashSet = new LinkedHashSet<String>();
        HashMap<String, Integer> myHashMap = new HashMap<String, Integer>();
        int before, after;
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String line = in.nextLine().toString();
            if (line == "") {
                continue;
            }
            String errAndNum = line.substring(line.lastIndexOf('\\') + 1);
            String[] sufAndNum = errAndNum.split(" ");
            String err = sufAndNum[0].substring(Math.max(0, sufAndNum[0].length() - 16));
            String num = sufAndNum[1];
            err = err + " " + num;
            before = myHashSet.size();
            myHashSet.add(err);
            after = myHashSet.size();
            if (before + 1 == after) {
                myHashMap.put(err, 1);
            } else if (before == after) {
                myHashMap.put(err, myHashMap.get(err) + 1);
            } else {
                System.out.println("ERROR during count duplicate times");
                System.exit(1);
            }
        }
        in.close();
        ArrayList<String> myArrList = new ArrayList<String>(myHashSet);
        int max = myArrList.size();
        int begin = Math.max(0, max - 8);
        for (int i = begin; i < max; i++) {
            System.out.println(myArrList.get(i) + " " + myHashMap.get(myArrList.get(i)));
        }
    }
}

发表于 2024-09-27 11:34:18 回复(0)
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.CopyOnWriteArrayList;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static Map<String ,String[] > errorMap = new HashMap<>();
    static List<String> list = new CopyOnWriteArrayList<>();
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        List<String> strError = new CopyOnWriteArrayList<>();
        while (in.hasNext()) { // 注意 while 处理多个 case
            strError.add(in.nextLine());
        }
        saveErrorImg(strError);
        int length = list.size()>8?list.size()-8:0;
        for(int i = length ; i < list.size() ; i++){
            System.out.println(list.get(i).substring(0,list.get(i).length() - errorMap.get(list.get(i))[0].length()) + " " + errorMap.get(list.get(i))[0] +" " + errorMap.get(list.get(i))[1]);
        }
    }
    private static void saveErrorImg(List<String> strError){
        for(String error : strError){
            String[] sError = error.split(" ");
            String s1= sError[0].substring(sError[0].lastIndexOf("\\")+1);
            String s2= s1.substring(s1.length()>16?s1.length()-16:0);
            String s3= s2+sError[1];
            if(errorMap.containsKey(s3)){
                errorMap.get(s3)[1] = Integer.parseInt(errorMap.get(s3)[1]) +1 +"";
            }else{
                errorMap.put(s3,new String[]{sError[1],"1"});
                list.add(s3);
            }
        }
    }
}

发表于 2024-09-05 21:40:07 回复(0)
想复杂了,其实用LinkedHashMap即可,最后遍历keyset,取最后8个值即可
坑点:
spilt分割“\”是split("\\\\")
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        
        HashMap<String, Integer> map = new HashMap<>();
        ArrayList<String> keyOrder = new ArrayList<>();
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String[] input = in.nextLine().split(" ");
            String[] arrKey = input[0].split("\\\\");
            String key = arrKey[arrKey.length-1];
            if (key.length()>16) {
                key = key.substring(key.length()-16);
            }
            key = key + " " + input[1];

            if (map.get(key)==null) {
                map.put(key, 1);
                keyOrder.add(key);
            } else {
                map.put(key, map.get(key)+1);
            }
        }

        int i = 0;
        if (keyOrder.size()>8) {
            i = keyOrder.size()-8;
        }
        for (; i<keyOrder.size(); i++) {
            System.out.println(keyOrder.get(i)+" "+map.get(keyOrder.get(i)));
        }
    }
}



发表于 2024-06-17 17:53:19 回复(0)
public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] result = new String[8];
        HashMap<String, Integer> map = new HashMap<>();
        int length = 0;
        while (in.hasNextLine()) {
            String str = in.nextLine();
            String strs[] = str.split(" ");
            String[] path = strs[0].split("\\\\");
            String name = path[path.length - 1];
            name = name.length() > 16 ? name.substring(name.length() - 16) : name;
            String s = name + " " + strs[1];
            if (map.get(s) != null) {
                map.merge(s, 1, Integer::sum);
            }else {
                map.put(s, 1);
                result[length % 8] = s;
                length++;
            }
        }
        // 打印
        int startIndex = length > 8 ? length % 8 : 0;
        length = Math.min(length, 8);
        for (int i = 0; i < length; i++) {
            String resultLine = result[(startIndex + i) % 8];
            System.out.println(resultLine + " " + map.get(resultLine));
        }
    }

发表于 2024-04-17 10:57:33 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {

    static List<Map<String, Integer>> records = new ArrayList();

    public static String getErrorMsg(String urlErr) {
        // 文件名称只保留16位
        String[] str = urlErr.split("\\\\");
        String[] fileAndRow = str[str.length - 1].split(" ");
        String file = fileAndRow[0];
        if (file.length() > 16) file = file.substring(file.length() - 16, file.length());
        return file + " " + fileAndRow[1];
    }

    public static void incr(String file) {
        Map<String, Integer> r = records.stream().filter(p -> p.containsKey(file)).findAny().orElse(null);
        if (r != null) {
            r.put(file, r.get(file) + 1);
        } else {
            r = new HashMap();
            r.put(file, 1);
            records.add(r);
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String str = in.nextLine();
            incr(getErrorMsg(str));
        }
        int start = records.size() > 8 ? records.size() - 8 : 0;
        for (; start < records.size(); ++ start) {
            Map<String, Integer> t = records.get(start);
            Set<String> key = t.keySet();
            key.forEach(k -> System.out.println(k + " " + t.get(k)));
        }
    }
}


编辑于 2024-03-23 21:57:17 回复(0)
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Map<String, Integer> map = new LinkedHashMap<>();
        while (in.hasNextLine()) {
            String[] arr = in.nextLine().split(" ");
            String name1 = arr[0].substring(arr[0].lastIndexOf("\\") + 1);
            String name = name1.length() > 16 ? name1.substring(name1.length() - 16) : name1;
            String line = arr[1];
            String key = name + " " + line;
            if (map.containsKey(key)) {
                map.put(key, map.get(key) + 1);
            } else {
                map.put(key, 1);
            }
        }

        int count = 0;
        for (String key : map.keySet()) {
            if (map.size() - count <= 8) {
                System.out.println(key + " " + map.get(key));
            }
            count ++;
        }
    }
}

编辑于 2024-03-06 21:09:36 回复(0)
import java.util.Scanner;
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        List<String> list = new ArrayList<>();
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String inString = in.nextLine();
            String[] split = inString.split("\\\\");
            
            String lastString = split[split.length - 1];
            String[] splitLast = lastString.split(" ");
            int length = splitLast[0].length();
            if (length>16){
                list.add(splitLast[0].substring(splitLast[0].length()-16)+" "+splitLast[1]);
            }else {
                list.add(lastString);
            }
        }

        LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (map.containsKey(s)){
                map.put(s,map.get(s) + 1);
            }else {
                map.put(s,1);
            }
        }

        int count = 0;
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (count >= map.size() -8){
                String key = entry.getKey();
                String[] split = key.split(" ");
                Integer value = entry.getValue();
                if (split[0].length() > 16){
                    System.out.println(split[0].substring(split[0].length()-16)+" "+split[1]+ " "+value);
                }else {
                    System.out.println(key + " "+value);
                }
            }
            count++;
        }
    }
}

编辑于 2023-12-04 15:43:14 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        LinkedHashMap<String, Integer> linkMap = new LinkedHashMap();
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String [] strArr = in.nextLine().split(" ");
            String [] s = strArr[0].split("\\\\");
            String filename = s[s.length-1];
            if(filename.length() > 16){
                filename = filename.substring(filename.length() - 16);
            }
            String record = filename + " " + strArr[1];
            linkMap.put(record, linkMap.getOrDefault(record, 0)+1);
        }
        int count = 0;
        for (Map.Entry<String, Integer> entry : linkMap.entrySet()) {
            count++;
            if(linkMap.size() > 8 && count > linkMap.size() - 8)
                System.out.println(entry.getKey()+" "+entry.getValue());
            else if(linkMap.size() <= 8){
                 System.out.println(entry.getKey()+" "+entry.getValue());
            }
        }
    }
}


发表于 2023-11-20 17:35:54 回复(0)
public static void maint(String[] args) throws IOException {
    Map<String, Integer> recMap = new LinkedHashMap<>();  Map<String, Integer> allRecords = new HashMap<>();  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  String line;  while ((line = br.readLine()) != null) {
        String[] errLines = line.split(" ");  String filename = errLines[0].substring(errLines[0].lastIndexOf("\\")+ 1);  String rowNum = errLines[1];  filename = filename.length() > 16 ? filename.substring(filename.length() - 16) : filename;  String key = filename+" " + rowNum;  if (!recMap.containsKey(key)) { if (!allRecords.containsKey(key)) { if (recMap.keySet().size() == 8) {
                    String oldKey = recMap.keySet().iterator().next();  allRecords.put(oldKey, recMap.get(oldKey));  recMap.remove(oldKey);  }
                recMap.put(key, 1);  allRecords.put(key, 1);  }
        } else {
            recMap.put(filename+" " + rowNum, recMap.get(filename+" " + rowNum) + 1);  } if (recMap.keySet().size()==8) { for (String errKey : recMap.keySet()) {
                System.out.println(errKey + " " + recMap.get(errKey));  }
        }
    }
}
发表于 2023-10-30 22:33:01 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Map<String, Integer> map1 = new HashMap<>();
        List<String> res = new ArrayList<>();
        while (in.hasNextLine()) {
            String s[] = in.nextLine().split(" ");
            String record = s[0].substring(s[0].lastIndexOf("\\") + 1);
            if (record.length() > 16) {
                record = record.substring(record.length() - 16);
            }

            if (map1.containsKey(record + " " + s[1])) {
                map1.put(record + " " + s[1], map1.get(record + " " + s[1]) + 1);
            } else {
                res.add(record + " " + s[1]);
                map1.put(record + " " + s[1], 1);
            }
        }
        int offset = res.size() > 8 ? res.size() - 8 : 0;
        for (int i = offset; i < res.size(); i++) {
            System.out.println(res.get(i) + " " + map1.get(res.get(i)));
        }

    }
}
发表于 2023-08-28 14:02:09 回复(0)
import java.util.Scanner;
import java.io.File;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    // 调试时 map里最终输出的结果已经对了,不知道怎么while完以后没下面的map遍历,以后找到了问题再回来改吧,各位大佬可以帮忙看看问题吗
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        Map<String,Map<String,Integer>> map = new HashMap<>();
        List<String> filePaths = new ArrayList<>();
        while (in.hasNext()){
            String line = in.next();
            int num = in.nextInt();
            String[] strings = line.split(" ");
            File file = new File(strings[0]);
            String filename = file.getName();
            if (filename.length() >16){
                filename = filename.substring(filename.length()-16);
            }
             String lineNum = String.valueOf(num);
            Map<String, Integer> map1 = map.get(filename);
            if (Objects.nonNull(map1) && (!(filePaths.isEmpty()) && !(filePaths.contains(file.getPath())))){
                if (Objects.nonNull(map1.get(lineNum))) {
                    map1.put(lineNum, map1.get(lineNum).intValue() + 1);
                }
            }else {
                map1 = new HashMap<>();
                map1.put(lineNum, 1);
            }
            filePaths.add(file.getPath());
            map.put(filename,map1);
        }
        for (Map.Entry<String, Map<String, Integer>> stringMapEntry : map.entrySet()) {
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(stringMapEntry.getKey());
            stringBuffer.append(" ");
            for (Map.Entry<String, Integer> stringIntegerEntry : stringMapEntry.getValue().entrySet()) {
                stringBuffer.append(stringIntegerEntry.getKey());
                stringBuffer.append(" ");
                stringBuffer.append(stringIntegerEntry.getValue());
            }
            System.out.println(stringBuffer.toString());
        }
    }
}

发表于 2023-08-27 15:48:53 回复(0)
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
           HashMap<String,Integer> record=new HashMap();

           List<String> list=new ArrayList();

           while(in.hasNextLine()){
               String line= in.nextLine();
               String str=line.substring(line.lastIndexOf("\\")+1);

                String [] sp=str.split(" ");
                if(sp[0].length()>16){
                    str=sp[0].substring(sp[0].length()-16)+" "+sp[1];
                }


               if(list.contains(str)){
                    record.put(str,record.get(str)+1);
               }else{
                    list.add(str);
                    record.put(str,1);
               }

           }

            int startIndex=list.size()>8?list.size()-8:0;

           for(int i=startIndex;i<list.size();i++){
             String s=list.get(i);
             
             System.out.print(s+" ");

             System.out.println(record.get(s));
           }

        }
    }
}

发表于 2023-08-07 21:11:35 回复(0)