错误记录统计

时间:2022-12-14 20:06:08
package a;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 *     开发一个简单错误记录功能小模块,能够记录出错的代码坐在的文件名称和行号。
    处理:
    1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
    2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
    3.输入的文件可能带路径,记录文件名称不能带路径
    输入描述:

一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

    文件路径为windows格式

    如:E:\V1R2\product\fpgadrive.c 1325
    E:\V1R2\product\fpgadrive.c 1325



输出描述:

将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1 

    结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。

    如果超过8条记录,则只输出前8条记录.

    如果文件名的长度超过16个字符,则只输出后16个字符


输入例子:

E:\V1R2\product\fpgadrive.c 1325


输出例子:

fpgadrive.c 1325 1

 * @author Jane
 *
 */
public class Main1 {
    public static void main(String []args){
        Scanner sc = new Scanner(System.in);
        //线性表中套线性表的方法来记录{{},{},{}},每组中都有文件名,行号,错误数量三个变量
        //用结构体来实现,重新定义一个类,用static 来计数  看能否用到。
        //或者用内部类来定义 (搞明白这三部分的知识点)
        class Record{
            private String name;
            private int line;
            private int count;
        }
        List <Record> recordList = new ArrayList<Record>(); 
        int i = 0; //标记遍历过的recordList的次数
        while(sc.hasNext()){
            String address = sc.next(); //文件地址
            int line = sc.nextInt();   //记录行号
            //从文件地址中取出文件名
            String name = getName(address);
            //判断recordList中是否已经存在正要存入的name,若存在,判断行数是否相同,若相同,count++;若不相同,recordList.add();
            
            int count = 1; //标记错误记录的个数
            if(recordList.size() == 0){
                Record record = new Record();
                record.name = name;
                record.line = line;
                record.count = count;
                recordList.add(record);
                //cs
//                System.out.println(record.name + " " + record.line + " " + record.count);
                i++;
//            } else if (i < recordList.size() + 1) {
            }else {
                //cs
                /*System.out.println(recordList.get(i - 1).name);
                System.out.println(recordList.get(i - 1).line);*/
                if (name.equals(recordList.get(i - 1).name )&& line == recordList.get(i - 1).line) {
                    recordList.get(i - 1).count++;
                } else {
                    Record record = new Record();
                    record.name = name;
                    record.line = line;
                    record.count = 1;
                    recordList.add(record);
                    i++;
                }

            }
        }
        
        sc.close();
        //比较文件名是否相同,若相同,再判断文件名长度是否超过16个字符,超过则只输出最后16个字符
        for (Record record : recordList) {
            if(record.count > 8) break;  //记录错误数目大于8的不输出
            if(record.name.length() > 16){
                record.name = getShortName(record.name);
            }
            System.out.println(record.name + " " + record.line + " " + record.count);
        }
    }
    

    private static String getShortName(String name) {
        // 文件名超过16个字符,取得最后16个字符作为名字
        String shortName = name.substring(name.length() - 16, name.length()-1);
        return shortName;
    }

    private static String getName(String address) {
        // 从地址中获取文件名称
//        String [] name2 = address.split("\\");  split一直出错,不知道“\”在split种怎么使用
        int index = address.lastIndexOf("\\");
        String name = address.substring(index + 1, address.length());
        return name;
    }

}

不能通过所有的测试用例,不知道错哪儿了

1.while(scanner.hasNext()){

      1. ctrl+z 表示输入结束。

       2.若想让scanner继续执行while后面的代码,需要在循环体末尾加一句“scanner.close()”,表示在控制台读到输入的“ctrl+z”之后,就终止while。否则while会无限循环,因 为scanner.hasNext(),空行也会被判为不为空的情况。

       3.再次未审清楚题目,题目中要求不输出错误次数高于8的,需要加一个判断。

       4. indexOf的用法:

    String.indexOf()的用法
        int index = str.lastIndexOf("\\");
            System.out.println(index);
            String name = str.substring(index+1, str.length());
            System.out.println(name);

 

正确代码附后

package a;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;


public class Main2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 线性表中套线性表的方法来记录{{},{},{}},每组中都有文件名,行号,错误数量三个变量
        // 用结构体来实现,重新定义一个类,用static 来计数 看能否用到。
        // 或者用内部类来定义 (搞明白这三部分的知识点)
        class Record implements Comparable<Record> { //内部类实现Compareble<Record>接口,并实现其方法,也就是定义排序规则,对类中的元素进行排序
//另一种排序方法是
private String name; private int line; private int count = 1; @Override public int compareTo(Record o) { // TODO Auto-generated method stub if (count != o.count) { return o.count - count; // count - o.count // 是从小到大排序;并且count相同的记录,也会按照list中的index的逆序排列 // o.count - count // 是从大到小排序,后一个记录的count减去前一个记录, } return 0; } } List<Record> recordList = new ArrayList<Record>(); // int i = 0; //标记遍历过的recordList的次数 while (sc.hasNext()) { int flag = 0; // 标记recordList种是否找到与正要插入的记录的文件名和行号都相同的记录 String address = sc.next(); // 文件地址 // 增加判断,若只有文件名,没有行号,则跳出本次循环 if (!sc.hasNextInt()) { continue; } int line = sc.nextInt(); // 记录行号 // 从文件地址中取出文件名 String name = getName(address); // 判断recordList中是否已经存在正要存入的name,若存在,判断行数是否相同,若相同,count++;若不相同,recordList.add(); // int count = 1; //标记错误记录的个数 // if(recordList.size() == 0){ // Record record = new Record(); // record.name = name; // record.line = line; // record.count = count; // recordList.add(record); //// i++; // }else { // 遍历已经建好的list,看其中是否有已经存在的文件名字和行数相同的record for (int j = 0; j < recordList.size(); j++) { if (name.equals(recordList.get(j).name) && line == recordList.get(j).line) { recordList.get(j).count++; flag = 1; break; // j++; } else { flag = 0; } } if (flag == 0) { Record record = new Record(); record.name = name; record.line = line; record.count = 1; recordList.add(record); } // //cs // System.out.println(recordList.size()); // j++; // //cs // System.out.println(recordList.size()); } sc.close(); // 对recordList进行排序 // Comparator<Record> comparator = new Comparator<Record>(); Collections.sort(recordList); // 比较文件名是否相同,若相同,再判断文件名长度是否超过16个字符,超过则只输出最后16个字符 // int max = recordList.get(0).count; // k的取值需要判断 int k = 8 < recordList.size() ? 8 : recordList.size(); for (k = 0; k < 8; k++) { // if(recordList.get(k).count > 8) break; // //记录错误数目大于8的不输出;(题目理解错误,题目的意思是只输出8条错误记录) // // if(recordList.get(k).name.length() > 16){ // recordList.get(k).name = getShortName(recordList.get(k).name); // //在排好序的列表中,因为输出要求而修改列表内容是不友好的 // // } // max = recordList.get(k).count > max ? recordList.get(k).count : // max; // 改为增加一个变量,来存储name值 int len = recordList.get(k).name.length(); int firstIndex = (len > 16) ? (len - 16) : 0; String nameout = (firstIndex == 0) ? recordList.get(k).name : recordList.get(k).name.substring(len - 16); System.out.println(nameout + " " + recordList.get(k).line + " " + recordList.get(k).count); } } // private static String getShortName(String name) { // // 文件名超过16个字符,取得最后16个字符作为名字 //// String shortName = name.substring(name.length() - 16, name.length()-1); // //为什么是-17,而不是-16? 是16.但是为什么 name.substring(name.length() - 16, name.length()-1) 只能输出15个字符 // String shortName = name.substring(name.length() - 16); // // return shortName; // } private static String getName(String address) { // 从地址中获取文件名称 // String [] name2 = address.split("\\"); split一直出错,不知道“\”在split种怎么使用 int index = address.lastIndexOf("\\"); String name = address.substring(index + 1, address.length()); return name; } }