首页 > 试题广场 >

简单错误记录

[编程题]简单错误记录
  • 热度指数:83475 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
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
推荐
L0L头像 L0L
//先将所有的字符串存入哈希表,key为字符串,value为<出现顺序,出现次数>,顺序取相同的字符串的最小值,次数一直累加
//排序的话,利用set重写比较器,按次数降序,次数相同则按出现顺序排列
//插入过程利用hash时间复杂度可以认为是O(n)
//排序过程set的是红黑树,可以认为是O(nlgn) ,总的复杂度就是这个了 
#include<iostream>
#include<unordered_map>
#include<set>
#include<string.h>
using namespace std;
struct info{//记录出现的顺序,和次数 
	int rank;
	int count;
	info(int rank,int count){
		this->rank=rank;
		this->count=count;
	}
};
struct fullinfo{//一条完整的结果,字符串和次数 
	string file;
	int rank;
	int count;
	fullinfo(string file,int rank,int count){
		this->file=file;
		this->rank=rank;
		this->count=count;
	}
};
struct classcomp {//set的比较器 
  bool operator()(const struct fullinfo& f1,const struct fullinfo& f2){
		if(f1.count==f2.count)
			return f1.rank<f2.rank;
		return f1.count>f2.count;
	}
};
typedef struct info INFO;
typedef struct fullinfo FULLINFO;
int main(){
	unordered_map<string,INFO> record;
	unordered_map<string,INFO>::iterator it;
	unordered_map<string,INFO>::const_iterator itfind;
	set<FULLINFO,classcomp> ret;
	set<FULLINFO,classcomp>::iterator sit;
	string linestr;//一行输入 
	string file;//文件名+行号 
	int pos;//空格的位置 
	int i=1;
	while(getline(cin,linestr)){
		if(linestr.length()==0)
			break;
		pos=linestr.rfind("\\");
		file=linestr.substr(pos+1);//拆分得到最后的filename和count 
		itfind=record.find(file);//在map中查看是否已经有了该字符串,没有则插入,有则次数加1 
		if(itfind==record.end()){
			INFO tmpi(i,1);
			record.insert(pair<string,INFO>(file,tmpi));
		}
		else{
			INFO tmpi(itfind->second.rank,itfind->second.count+1);
			record.erase(file);
			record.insert(pair<string,INFO>(file,tmpi));
		}
		i++;
	}
	for(it=record.begin();it!=record.end();it++){
		FULLINFO tmpfull(it->first,it->second.rank,it->second.count);//构建排序的set集合 
		ret.insert(tmpfull);
	}
	for(i=0,sit=ret.begin();sit!=ret.end()&&i<8;++sit,++i){//最多输出8条记录,file少于16位 
		if(file.find(" ")<=16){ 
			cout<<(*sit).file<<" "<<(*sit).count<<endl;
			} 
		else{
			cout<<(*sit).file.substr(file.find(" ")-16)<<" "<<(*sit).count<<endl;
		} 
		
	}
	return 0;
} 

编辑于 2015-11-14 14:14:24 回复(28)
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.hasNextLine()) {
			String s = sc.nextLine();
			if(s == null || "".equals(s)) break;
			String[] split = s.split("\\s");
			String key = split[0].substring(split[0].lastIndexOf('\\') + 1) + " " + split[1];
			map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
		}
		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[] split = list.get(i).getKey().split("\\s");
			if(split[0].length() > 16) split[0] = split[0].substring(split[0].length() - 16);
			System.out.println(split[0] + " " + split[1] + " " + list.get(i).getValue());
		}
	}
}

编辑于 2017-07-23 22:20:00 回复(4)

只要知道可以使用文件名加上行数作为map的key,此题不难的

import java.util.*;

/**
 * 华为02-简单错误记录
 *
 * 第一次思路:因为一直在想如何使文件名如何对应多个行数的解决方法,卡了好多大会
 * 就这样越想越复杂,但是基本思路有了。
 * 就是用一个map记录文件名及其对应的在list中索引(由自增序号自动生成)。
 * list是用来存放新建的不重复的错误。
 * 这样我们每次对于一个新的错误,首先看map中是否有
 * 若有,我们通过索引找到list中的对应node,更新其次数
 * 若没有,map中存放文件名及其自增序号,同时在list中添加一条新的错误记录
 * 最后我们排序,取出前8个即可。
 * 
 * 技巧:
 * 1.如何解决文件名如何对应多个行数
 * 我擦,直接令文件名加上行数当成key就可以了啊!!!太妙了
 * 2.我们只需在list中添加错误记录时,注意要对超过16的处理一下
 * 3.Collection.sort()可以使用lambda表达式哦
 * Create by Special on 2018/2/14 22:01
 */
public class Main {

    static Map<String, Integer> fileOriginName;
    static List<Node> nodes = new ArrayList<>();

    static class Node{
        String name;
        int count;

        public Node(String name){
            this.name = name;
            this.count = 1;
        }

        public void add(int value){
            count += value;
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        fileOriginName = new HashMap<>();
        String fileName;
        int count = 0, index;
        while(input.hasNext()){
            fileName = input.nextLine();
            fileName = fileName.substring(fileName.lastIndexOf('\\') + 1);
            if(fileOriginName.containsKey(fileName)){
                nodes.get(fileOriginName.get(fileName)).add(1);
            } else{
                fileOriginName.put(fileName, count++);
                index = fileName.indexOf(' ');
                fileName = index > 16 ? fileName.substring(index - 16) : fileName;
                nodes.add(new Node(fileName));
            }
        }
        Collections.sort(nodes, (node1, node2) -> {
            return node2.count - node1.count;
        });
        Node node;
        for(int i = 0; i < Math.min(8, nodes.size()); i++){
            node = nodes.get(i);
            System.out.println(node.name + " " + node.count);
        }
    }
}
发表于 2018-02-14 23:33:27 回复(2)
#include<iostream>
#include<string.h>
#include<memory.h>

using namespace std;
struct SRecord
{
	int cnterror;
	int lineNum;
	char fileName[17];
	char fileNameNumstr[40];
	SRecord *next;
};
int Insert(SRecord *head,SRecord *pSR)
{
	SRecord *cur=head->next;
	SRecord *preCur=head;
	while (cur)
	{
		if(!strcmp(cur->fileNameNumstr,pSR->fileNameNumstr))
		{
			cur->cnterror++;
			return 0;
		}
		preCur=cur;
		cur=cur->next;
	}
	pSR->cnterror++;
	preCur->next=pSR;
	pSR->next=nullptr;
	return 1;
}
void print(SRecord *head)
{
	if(!head->next)
		return ;
	SRecord *cur=head->next;
	SRecord *maxp=cur;
	SRecord *preMax=head;
	SRecord *preCur=head;
	while (cur)
	{
		if(cur->cnterror>maxp->cnterror)
		{
			preMax=preCur;
			maxp=cur;
		}
		preCur=cur;
		cur=cur->next;
	}
		cout<<maxp->fileName<<' '<<maxp->lineNum<<' '<<maxp->cnterror<<endl;
		preMax->next=maxp->next;
		delete maxp;
}
void desSR(SRecord *head)
{
	SRecord *cur=head;
	head=head->next;
	delete cur;
	while (head)
	{
		cur=head;
		head=head->next;
		delete cur;
	}
}
int main()
{
	char str[200];
	SRecord *pSR;
	SRecord *head=new SRecord;
	head->next=nullptr;
	while (cin.getline(str,sizeof(str)))
	{
		if (!strlen(str))
		{
			break;
		}
		char *token,*laststr;
		token=strtok(str,"\\");
		laststr=token;
		while (token)
		{
			laststr=token;
			token=strtok(nullptr,"\\");
		}

		pSR=new SRecord;
		memset(pSR,0,sizeof(SRecord));
		strcpy(pSR->fileNameNumstr,laststr);
		token=strtok(laststr," ");
		char fileNamestr[40],*pfileNamestr=token;
		strcpy(fileNamestr,token);
		int fileNamelen=strlen(fileNamestr);
		if(fileNamelen>=17)
		{
			fileNamelen-=16;
			pfileNamestr+=fileNamelen;
		}

		strcpy(pSR->fileName,pfileNamestr);
		token=strtok(nullptr," ");
		pSR->lineNum=atoi(token);
		
		//cout<<laststr<<endl<<pSR->fileName<<endl<<pSR->lineNum<<endl;	
		Insert(head,pSR);
	}
	for(int i=0;i<8;++i)
	print(head);

	desSR(head);
	//system("PAUSE");
	return 0;
}

发表于 2016-07-17 11:23:45 回复(4)
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;

typedef struct re{
    char docinfo[100];//文件名
	char ronu[10];//错误行号
    int docdisplaypos;//要从哪里开始展示文件
    int repos;//错误的初始位置
    int errcnt;//错误数量
}Record;

void quicksort(Record re[],int start,int last){
	if(start>=last){
		return ;
	}
    int left = start,pos=left+1,right=last;
    Record pivot = re[start],tmp;
    while(left != right){
        if(re[pos].errcnt < pivot.errcnt){
            tmp = re[right];
            re[right--] = re[pos];
            re[pos] = tmp;
        }else if(re[pos].errcnt > pivot.errcnt){
            re[left++] = re[pos++];
        }else{
            if(re[pos].repos<pivot.repos){
                re[left++] = re[pos++]; 
            }else{
                tmp = re[right];
                re[right--] = re[pos];
                re[pos] = tmp;
            }
        }
    }
    re[left] = pivot;
    quicksort(re,start,left-1);
    quicksort(re,left+1,last);
}

/*测试用例
E:\V1R2\product\fpgadrivea.c1111 1325
E:\V1R2\product\fpgadrivea.c11112 125
E:\V1R2\product\fpgadrive.c 1325
E:\V1R2\productss\fpgadrive.c 1325
E:\V1R2\product\fpgadrivea.c11112 1335

*/

Record reco[100];

int main(void){
    char s[300],rownum[10];

    char *pdoc;
    int doclength;
    int recnt = 0;
    int hasflag;
    while(cin>>s>>rownum){
       pdoc = strrchr(s,'\\');

       hasflag = 0;
       for(int i = 0; i<recnt;i++){
           if( 0 == strcmp(pdoc+1,reco[i].docinfo)){
			   if( 0 == strcmp(rownum,reco[i].ronu)){
				   reco[i].errcnt++;
				   hasflag = 1;
				   break;
			   }
           }
       }
       if( 1 == hasflag){
           continue;
       }
       strcpy(reco[recnt].docinfo,pdoc+1);
       strcpy(reco[recnt].ronu,rownum);
	   
       reco[recnt].repos = recnt;
       doclength = strlen(reco[recnt].docinfo);
       if( doclength > 16 ){
           reco[recnt].docdisplaypos = doclength-16;
       }else{
           reco[recnt].docdisplaypos = 0;
       }
       reco[recnt].errcnt = 1;
       recnt++;
	   
    }
    quicksort(reco,0,recnt-1);
    recnt = recnt>8?8:recnt;
	for(int i=0;i<recnt;i++){
		printf("%s %s %d\n",&reco[i].docinfo[reco[i].docdisplaypos],reco[i].ronu,reco[i].errcnt);
			
	}
    return 0;
}


题目不是很难,可是总感觉这不是笔试题,而很有可能是面试题。而且,这么大的代码量,即使是面试也应该不会让你写完整的代码吧。
这道题有很多种方法,如果是面试出这种题不仅可以考察思维,还可以考察应试者的代码习惯等等

发表于 2016-09-08 16:53:17 回复(1)
from collections import OrderedDict
def solution(lines):
    records = OrderedDict()  # 有序字典,便于后期稳定输出
    
    for e in lines:
        line = e.split()
        name = line[0].split('\\')[-1]
        if (name, line[1]) not in records:records[(name, line[1])] = 1
        else:records[(name, line[1])] += 1
    return records
    

import sys

try:
    while True:
        lines = sys.stdin.readlines()
        # print lines
        if not lines:
            break
        ret = solution(lines)
        # print ret
        #result = zip(ret.keys(), ret.values())
        result = sorted(ret.iteritems(),key=lambda x:x[1], reverse=True) # 本身按递增排序的结果就是不稳定的,reverse之后就满足了。。
        # print result
        # print result[:8]
        
        for e in result[:8]:
            if len(e[0][0]) > 16:print e[0][0][-16:],e[0][1],e[1]
            else: print e[0][0],e[0][1],e[1]
            
        
except:
    # print result
    pass

发表于 2016-08-21 00:26:30 回复(0)
大家帮忙运行一下我的程序,为什么能得出结果,但是提交的时候说是程序有错误? package com.huawei.subject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class RecordError {

	private static Map<String, Object> map;
	private static List<Map<String, Object>> list;

	public static void main(String args[]) {
		Scanner sc = new Scanner(System.in);
		String file, fileName, midFileName;
		int errorLine, errorCount, lastIndex;
		
		list = new ArrayList<Map<String, Object>>();
		while (sc.hasNext()) {  
			map = new HashMap<String, Object>();
			file = sc.next(); // 输入的原始文件名(包括路径)
			if (file.equals("quit")) {  //跳出循环
				break;
			}
			StringBuilder sb = new StringBuilder();
			lastIndex = file.lastIndexOf("\\");
			sb.append(file.substring(lastIndex + 1));
			fileName = sb.toString();
		//	System.out.println("---"+file);
			// if (midFileName.lastIndexOf(" ") - 16 > 0) {//
			// 如果文件名超过16位。则去后16位
			// lastIndex = midFileName.lastIndexOf(" ") - 16;
			// fileName = midFileName.substring(lastIndex);
			// } else {
			// fileName = midFileName; // 文件名
			// }
			errorLine = sc.nextInt();
			errorCount = 1;
			int flag = 0;
			for (int i = 0; i < list.size(); i++) {
				if (list.get(i).get("fileName").toString().equals(fileName)
						&& Integer.parseInt(list.get(i).get("errorLine").toString()) == errorLine) {
					errorCount = Integer.parseInt(list.get(i).get("errorCount").toString()) + 1;
					list.get(i).put("errorCount", errorCount);
					flag = 1;
				}
			}
			// map.put("errorCount", errorCount);
			if (flag == 0) {
				map.put("fileName", fileName);
				map.put("errorLine", errorLine);
				map.put("errorCount", errorCount);
				list.add(map);
			}

		}
		sc.close();
		for (int i = 0; i < list.size(); i++) {
			midFileName = list.get(i).get("fileName").toString();
			if (midFileName.lastIndexOf(" ") - 16 > 0) {// 如果文件名超过16位。则去后16位
				lastIndex = midFileName.lastIndexOf(" ") - 16;
				fileName = midFileName.substring(lastIndex);
				list.get(i).put("fileName", fileName);
			}
		}

		Comparator<Map<String, Object>> cmp = new Comparator<Map<String, Object>>() {  
			@Override
			public int compare(Map<String, Object> m1, Map<String, Object> m2) {
				return Integer.parseInt(m1.get("errorCount").toString())
						- Integer.parseInt(m2.get("errorCount").toString()) == 0 ? 0
								: Integer.parseInt(m2.get("errorCount").toString())
										- Integer.parseInt(m1.get("errorCount").toString());
			}
		};
		Collections.sort(list, cmp);
        if(list.size()<=8){
        	for (Map map : list) {
    			System.out.print(map.get("fileName") + " " + map.get("errorLine") + " " + map.get("errorCount")+"  ");

    		}
        }else{
        	for(int i=0;i<8;i++){
        		System.out.print(list.get(i).get("fileName") + " " + list.get(i).get("errorLine") + " " + list.get(i).get("errorCount")+" ");
        	}
        	
        }
		

	}
} 


发表于 2016-08-10 10:15:50 回复(0)
/**
 * 好像Java答案不多,我来献丑吧。
 * 正如大家之前所说,这个题主要是考细节。所以我只说说代码的细节:
 *   1. 读到文件路径,先用substring截取文件名。
 *   2. 用Entry对象保存单个记录和出现次数。
 *   3. 用Map来区分是否为新纪录,这要求Entry重新equals和hashCode。
 *   4. 真正使用的是LinkedHashMap,使得遍历key时可以按照插入顺序遍历,满足了题目要求。
 *   5. Arrays.sort对引用类型采用插入排序+归并排序,保证了排序稳定性,满足了题目要求。
 *   6. Entry实现了Comparable接口,其实更好是写一个Comparator,因为是刷题无所谓了。
 *   7. 对文件名长度的判定在Entry的toString中,这样写不好,因为是刷题无所谓了。
 **/
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Scanner;

public class Main{
	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		HashMap<Entry, Entry> records = new LinkedHashMap<Entry , Entry>();
		while(scan.hasNext()){
			String name = scan.next();
			int lines = scan.nextInt();
			int index = name.lastIndexOf('\\');
			//截取文件名
			if(index!=-1)
				name = name.substring(index+1);
			//生成Entry
			Entry entry = new Entry(name,lines);
			if(records.containsKey(entry)){
				//合并
				Entry old = records.get(entry);
				old.count++;
			}else{
				//新的
				records.put(entry, entry);
			}
		}  scan.close();  //获得结果
		Entry[] result = new Entry[records.size()];
		result = records.keySet().toArray(result);
		Arrays.sort(result);
		//输出结果
		int size = Math.min(8, result.length);
		for(int i=0;i<size;i++){
			System.out.println(result[i]);
		}
	}
	
	private static class Entry implements Comparable<Entry>{
		public String 	name;
		public int		lines;
		public int		count;
		
		public Entry(String n , int l){
			this.name = n;
			this.lines = l;
			this.count=1;
		}
		@Override
		public int compareTo(Entry e) {
			if(this.count<e.count)
				return 1;
			else if(this.count == e.count)
				return 0;
			else
				return -1;
		}
		@Override
		public int hashCode(){
			return name.hashCode()+lines;
		}
		@Override
		public boolean equals(Object obj){
			if(obj==this)
				return true;
			if(obj instanceof Entry){
				Entry e = (Entry)obj;
				if(e.name.equals(this.name)&&e.lines==this.lines)
					return true;
			}
			return false;
		}
		@Override
		public String toString(){
			if(name.length()<=16)
				return name+" "+lines+" "+count;
			else
				return name.substring(name.length()-16,name.length())+" "+lines+" "+count;
		}
	}
}

发表于 2016-08-05 18:10:59 回复(2)
Ron头像 Ron
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Scanner;

class ByValueComparator implements Comparator<String>{
	HashMap<String, Integer> base_map;
	public ByValueComparator(HashMap<String,Integer> map) {
		// TODO Auto-generated constructor stub
		this.base_map = map;
	}
	@Override
	public int compare(String str1, String str2) {
		// TODO Auto-generated method stub
		if(!base_map.containsKey(str1) || !base_map.containsKey(str2)){
			return 0;
		}
		if(base_map.get(str1) < base_map.get(str2)){
			return 1;
		}else{
			//相等也要返回-1,否则在排序时不会把相等的值放到TreeMap中,若=0则新值替代原值
			//为何相等是返回-1不是返回1,根据情况而定,返回1代表新值放到旧值前面,-1代表新值放在旧值后面
			return -1;
		}
	}
}
public class juan1_q2 {
	public static void main(String[] ags){
		HashMap<String, Integer> recMap = new HashMap<String, Integer>();
		Scanner input = new Scanner(System.in);
		String file = "";
		int errorLine = 0;
		int lastIndex = 0;
		String recName = null;
		while(input.hasNext()){
			file = input.next();
			errorLine = input.nextInt();
			lastIndex = file.lastIndexOf("\\");
			recName = (lastIndex < 0)?file:file.substring(lastIndex+1)+" "+errorLine;
			int count = 0;
			if(!recMap.containsKey(recName)){
				recMap.put(recName, 1);
			}else{
				count = recMap.get(recName);
				recMap.put(recName, count+1);
			}
		}
		input.close();
		//--------以上统计,以下排序取值-------------
		ArrayList<String> keys = new ArrayList<String>(recMap.keySet());
		ByValueComparator bvc = new ByValueComparator(recMap);
		Collections.sort(keys, bvc);
		for(int i = 0;i < (keys.size() > 8?8:keys.size());i++){
			String key = keys.get(i);
			StringBuilder res = new StringBuilder();
			lastIndex = key.lastIndexOf(" ");
			int value = recMap.get(key);
			if(lastIndex > 16){
				res.append(key.substring(lastIndex-16));
			}else{
				res.append(key);
			}
			res.append(" "+value);
			System.out.println(res.toString());
		}
	}
}
以上代码有两个问题:
1.comparator理解问题,返回1代表str1会放在str2后面,-1代表str1放在str2前面,若相等应该是返回0.
2.没有考虑输入顺序的排序,因此要使用LinkedHashMap代替HashMap来保存输入顺序的信息
修改代码通过,如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Scanner;

class ByValueComparator implements Comparator<String>{
	HashMap<String, Integer> base_map;
	public ByValueComparator(HashMap<String,Integer> map) {
		// TODO Auto-generated constructor stub
		this.base_map = map;
	}
	@Override
	public int compare(String str1, String str2) {
		// TODO Auto-generated method stub
		if(!base_map.containsKey(str1) || !base_map.containsKey(str2)){
			return 0;
		}
		if(base_map.get(str1) < base_map.get(str2)){
			return 1;
			
		}else if(base_map.get(str1) > base_map.get(str2)){
			//从大到小排序,因此若str1<str2,则返回1,即str2会排在str1前面;str1>str2,返回-1,则str1排在str2前面
			//从小到大排序,-1代表str1<str2;0代表==,不动位置;1代表str1>str2,str1放在str2后。
			return -1;
		}else{
			return 0;
		}
	}
}
public class juan1_q2 {
	public static void main(String[] ags){
		LinkedHashMap<String, Integer> recMap = new LinkedHashMap<String, Integer>();
		Scanner input = new Scanner(System.in);
		String file = "";
		int errorLine = 0;
		int lastIndex = 0;
		String recName = "";
		while(input.hasNext()){
			file = input.next();
			errorLine = input.nextInt();
			lastIndex = file.lastIndexOf("\\");
			recName = (lastIndex < 0)?file:file.substring(lastIndex+1)+" "+errorLine;
			int count = 0;
			if(!recMap.containsKey(recName)){
				recMap.put(recName, 1);
			}else{
				count = recMap.get(recName);
				recMap.put(recName, count+1);
			}
		}
		input.close();
		//--------以上统计,以下排序取值-------------
		ArrayList<String> keys = new ArrayList<String>(recMap.keySet());
		System.out.println(keys.toString());
		ByValueComparator bvc = new ByValueComparator(recMap);
		Collections.sort(keys, bvc);
		System.out.println(keys.toString());
		for(int i = 0;i < (keys.size() > 8?8:keys.size());i++){
			String key = keys.get(i);
			StringBuilder res = new StringBuilder();
			lastIndex = key.lastIndexOf(" ");
			int value = recMap.get(key);
			if(lastIndex > 16){
				res.append(key.substring(lastIndex-16));
			}else{
				res.append(key);
			}
			res.append(" ").append(value);
			System.out.println(res.toString());
		}
	}
}

编辑于 2016-04-05 16:24:33 回复(10)
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

bool compare(pair<string, int> a, pair<string, int> b){
	return a.second > b.second;
}
int main(void){
	string input, file;
	vector<pair<string, int>> errors;
	while (getline(cin, input)){
		if (input.size() == 0)
			break;
		unsigned int f = input.rfind('\\');
		file = input.substr(f + 1);
		errors.push_back(make_pair(file, 1));
		for (int i = 0; i<(errors.size() - 1); i++){
			if (errors[i].first == file){
				errors[i].second++;
				errors.pop_back(); break;
			}
		}
	}
	stable_sort(errors.begin(), errors.end(), compare);
	int idx = 0;
	while (idx<8 && idx<errors.size()){
		string check = errors[idx].first;
		int t = check.find(' ');
		if (t>16)
			errors[idx].first.erase(0, t - 16);
		cout << errors[idx].first << ' ' << errors[idx].second << endl;
		idx++;
	}
}

发表于 2015-09-07 22:06:05 回复(53)
1.注意输出8条记录
2.注意这里文件名包括后缀(坑)
import java.util.*;
public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<ErrorLine> list = new ArrayList<>();
        while (scanner.hasNext()) {
            String line = scanner.nextLine();
            int id = line.lastIndexOf('\\');
            line = id<0  ? line : line.substring(id+1);

            boolean t = false;
            for (ErrorLine e : list) {
                if (line.equals(e.line)) {
                    t = true;
                    e.count++;
                }
            }
            if (!t) {
                list.add(new ErrorLine(line, 1));
            }
            t = false;
        }
        scanner.close();

        Collections.sort(list);

        int n = list.size() >= 8 ? 8 : list.size();
        for (int i = 0; i < n; i++) {
            String[] s = list.get(i).line.split(" ");
            s[0] = s[0].length()>16 ? s[0].substring(s[0].length()-16) : s[0];
            System.out.println(s[0] + " " + s[1] + " " + list.get(i).count);
        }
    }
}

class ErrorLine implements Comparable<ErrorLine> {
    public String line;
    public int count;

    public ErrorLine(String line, int count) {
        this.line = line;
        this.count = count;
    }

    @Override
    public int compareTo(ErrorLine e) {
        return e.count - this.count;
    }
}


发表于 2022-04-28 00:23:35 回复(0)
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
struct data1 {
    string a;
    int errorcount = 0;
    int errorline;
}datalist[1000];
bool cmp(data1 a, data1 b) 

    return a.errorcount>b.errorcount;

}
int main() {
    int datalistindex = 0,diwei=1, xiegangindex, errorline; string process;
    while (getline(cin, process, ' ') && cin >> errorline ) {
        for (int i = process.length() - 1; i >= 0; i--) if (process[i] == '\\') { xiegangindex = i + 1; break; }
        process = process.substr(xiegangindex, process.length());
        if (datalistindex == 0)
        {
            datalist[datalistindex].errorline = errorline;
            datalist[datalistindex].a = process;
            datalist[datalistindex++].errorcount++;
        }
        else
        {
            bool find = false;
            for (int i = 0; i < datalistindex; i++) {
                if (datalist[i].errorline == errorline && datalist[i].a.compare(process) == 0)
                {
                    datalist[i].errorcount++; find = true; break;
                }
            }
            if (find == false)
            {
                datalist[datalistindex].errorline = errorline;
                datalist[datalistindex].a = process;
                datalist[datalistindex++].errorcount++;
            }
        }
        process = "";
    }
    stable_sort(datalist, datalist + datalistindex, cmp);
    for (int i = 0; i < datalistindex &&i<8; i++) 
    {
    if(datalist[i].a.length()>15) datalist[i].a= datalist[i].a.substr(datalist[i].a.length()-16, datalist[i].a.length());
    cout << datalist[i].a << " " << datalist[i].errorline << " " << datalist[i].errorcount << endl;
    }
    return 0;
}
发表于 2022-03-23 19:51:27 回复(0)
用的C++,使用牛客的测试数据在本地VS上测试了,输出和答案是一致的,也不会报错。但是牛客网站一直提示:
您的代码已保存
运行错误:请检查是否存在数组、列表等越界非法访问,内存非法访问等情况
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr: __pos (which is 18446744073709551614) > this->size() (which is 17)
代码如下,有没有大佬能看出什么玄机,不胜感激!😂
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int outNum = 8; // 输出记录的数目
int nameLen = 16; //输出名字字符长度的上限
struct ErrRec{
    string s_Name;
    string s_LineNum;
    int s_Count = 0;
};

// 获取接收信息
vector<ErrRec>getInfo(vector<ErrRec>& result){
    string line;
    while (getline(cin, line)){
        int spaceIndex = line.find(' ');
        int slashIndex = line.find_last_of('\\');
        ErrRec individual;
        string lineNum = line.substr(spaceIndex + 1);
        string name = line.substr(slashIndex + 1, spaceIndex - slashIndex - 1);
        if (result.size() == 0){
            individual.s_LineNum = line.substr(spaceIndex + 1);
            individual.s_Name = line.substr(slashIndex + 1, spaceIndex - slashIndex - 1);
            individual.s_Count = 1;
            result.push_back(individual);
        }
        else{
            bool sign = false;
            // 遍历ErrRec的所有数据,判断当前记录是否已经被记录
            for (vector<ErrRec>::iterator it = result.begin(); it != result.end(); it++){
                // 当前错误已经被记录,计数+1
                if ((*it).s_LineNum == lineNum && (*it).s_Name == name){
                    (*it).s_Count++;
                    sign = true;
                    break;
                }
            }
            // 当前错误未被记录,在vector末端存入当前记录
            if (!sign){
                individual.s_LineNum = line.substr(spaceIndex + 1);
                individual.s_Name = line.substr(slashIndex + 1, spaceIndex - slashIndex - 1);
                individual.s_Count = 1;
                result.push_back(individual);
            }
        }
    }
    return result;
}

// 排序的自定义降序规则
bool compareRule(ErrRec a, ErrRec b){
    return a.s_Count > b.s_Count;
}

// 输出当前vector中的错误记录
void printResult(vector<ErrRec>& result){
    int printNum = 0;
    for (vector<ErrRec>::iterator it = result.begin(); it != result.end(); it++){
        // 判断当前记录的数目是否超过outNum,若超过则只输出前8个
        if (printNum == outNum){
            break;
        }

        // 判断it指向的错误记录的名字是否超过16个字符,若超过则作截断
        else{
            if ((*it).s_Name.length() > nameLen){
                int pose = nameLen - (*it).s_Name.length() - 1;
                string blockName = (*it).s_Name.substr(pose, nameLen);
                cout << blockName << " " << (*it).s_LineNum << " " << (*it).s_Count << endl;
            }
            else
                cout << (*it).s_Name << " " << (*it).s_LineNum << " " << (*it).s_Count << endl;
        }
        printNum++;
    }
}

int main(){
    vector<ErrRec> result;
    result = getInfo(result);
    stable_sort(result.begin(), result.end(), compareRule);
    printResult(result);
    system("pause");
    return 0;
}


编辑于 2021-04-07 21:03:12 回复(0)
结构体
#include<iostream>
#include <queue>
#include<algorithm>
using namespace std;
struct Note{
    string path;
    int line;
    int count;
    int c;
};
bool cmp(Note A,Note B){
    if(A.count==B.count) return A.c<B.c;
    return A.count>B.count;
}
int main(){
    string path;
    int line;
    vector<Note> vec;
    int p=0;
    while(cin>>path>>line){
        int pos=path.find_last_of('\\');
        string filename(path.substr(pos+1));
        if(filename.size()>16) filename=filename.substr(filename.size()-16);
        bool flag=false;
        for(int i=0;i<vec.size();i++){
            if(filename==vec[i].path&&line==vec[i].line){//存在时则更新
                vec[i].count++;
                flag==true;
                break;
            }
        }
        if(!flag){//不存在时则插入
            Note tempNote={filename,line,1,p++};
            vec.push_back(tempNote);
        }
    }
    sort(vec.begin(),vec.end(),cmp);
    for(int i=0;i<8;i++){
        cout<<vec[i].path<<" "<<vec[i].line<<" "<<vec[i].count<<endl;
    }
    return 0;
}

发表于 2021-04-06 21:38:48 回复(0)
全STL写的,以pair作为key,直接从写了map对key的比较规则。
#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;
#define x first
#define y second

struct cmp
{
    bool operator()(const PII &p1,const PII &p2)
    {
        if(p1.x==p2.x)    return p1.y<p2.y;
        return p1.x>p2.x;
    }
};

int main()
{
    unordered_map<string,unordered_map<int,PII>> mp;
    string s;
    int line,cnt=0;
    
    while(cin>>s>>line)
    {
        int pos=s.rfind("\\",s.size()-1);
        if(pos!=string::npos)
        {
            s=s.substr(pos+1);
        }
        if(!mp.count(s))
        {
            mp[s][line].x++;
            mp[s][line].y=cnt++;
        }
        else if(mp.count(s) && !mp[s].count(line))
        {
            mp[s][line].x++;
            mp[s][line].y=cnt++;
        }
        else if(mp.count(s) && mp[s].count(line))
        {
            mp[s][line].x++;
        }       
    }
    
    map<PII,pair<string,int>,cmp> _map;
    for(auto &p:mp)
    {
        for(auto &pson:p.y)
        {
            _map.insert({pson.y,{p.x,pson.x}});
        }
    }
    int num=0;
    for(auto &p:_map)
    {
        if(num>=8) break;
        string &str=p.y.x;
        if(str.size()>16)    cout<<str.substr(str.size()-16);
        else cout<<str;
        cout<<" "<<p.y.y<<" "<<p.x.x<<endl;
        num++;
    }
    return 0;
}


发表于 2020-09-08 20:20:36 回复(0)
def judge_in(str_in,ans): //判断相同的错误记录函数,返回布尔值以及当前出现次数
    for i in ans:
        if str_in in i[0]:
            return [True,i[1]]
    return [False,0]
try:
    ans = []
    while True: //坑爹的判题器,无限接收样例输入
        ans_str = ''
        line = input().split()
        road = line[0]
        code = int(line[1])
        temp = road.split("\\")
        filename = temp[-1]
        sym = judge_in(filename+' '+str(code),ans)
        if sym[0]: //取布尔类型的值做判断是否是重复错误
            index = ans.index([filename+' '+str(code),sym[1]])
            ans[index][1] +=1
        else:
            ans_str += filename + ' ' + str(code)
            ans.append([ans_str,1])
except:
    ans = sorted(ans,key=lambda x:x[1],reverse=True)//按照出现次数排序
    for i in range(8):
        tp = ans[i][0].split()
        if len(tp[0])>16://判断字符是否不符合16个,进行差异化输出
            print(tp[0][-16:],tp[1],ans[i][1])
        else:
            print(ans[i][0],ans[i][1])
此乃python3的强行破解法,按照题目要求一步一步的写
发表于 2020-08-22 03:25:43 回复(0)
import java.util.*;

public class Main{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        HashMap<String,Integer> hashmap = new HashMap<>();
        List<String> arraylist = new ArrayList<>();

        while(sc.hasNext())
        {
            String[] info = sc.nextLine().split("\\\\");
            String parseInfo = info[info.length - 1];
            if(arraylist.contains(parseInfo)){
                hashmap.put(parseInfo,hashmap.get(parseInfo)+1);
            }else{
                arraylist.add(parseInfo);
                hashmap.put(parseInfo,1);
            }
        }
        int temp = 1;
        arraylist.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if(hashmap.get(o1)<hashmap.get(o2)){
                    return 1;
                }else if(hashmap.get(o1)>hashmap.get(o2)){
                    return -1;
                }else{
                    if (arraylist.indexOf(o1)>arraylist.indexOf(o2)){
                        return 1;
                    }else{
                        return -1;
                    }
                }
            }
        });
        sc.close();
        for (String s : arraylist ){
            if(temp>8){
                break;
            }
            temp++;
            int length = s.split(" ")[0].length();
            int cut_l = length - 16;
            int olength = s.length() - cut_l;
            if(length<=16){
                System.out.println(s+" "+hashmap.get(s));
            }else
            {
                System.out.println(s.substring(s.length()-olength,s.length())+" "+hashmap.get(s));
            }
        }
        
    }
}

发表于 2020-04-19 18:30:53 回复(0)
pre_knowledge:
sorted(res.items(), key=lambda x: x[1], reverse=True)  
#可以对字典res的values进行排序

(10, 3) > (10, 2) > (9, 5)
(2956)# tuple的大小比较
完整代码:
res = {}
i = 0
while True:
    try:
        s = input()
        file_error = s.split('\\')[-1]
        found = False
        for key in res.keys():
            if file_error in key:
                res[key] = (res[key][0]+1, res[key][1]) # 数量+1
                found = True
        if not found:
            file_error_key = '{}'.format(file_error)
            res[file_error_key] = (1, 9999-i)  (2957)# 把数量和出现次数放入键值
            i += 1
    except:
        break
sort_res = sorted(res.items(), key=lambda x: x[1], reverse=True)
for i in range(min(8, len(sort_res))):
    name, num = sort_res[i]
    name = name.split(' ')
    file_name, error = ''.join(name[:-1]), name[-1]
    file_name = file_name[-16:]
    print('{} {} {}'.format(file_name, error, num[0]))



发表于 2020-03-19 13:19:49 回复(0)
JavaScript
这道题本身不难,但是因为OJ和审题的原因让我费了很大的力气;
踩坑:
1.不知道是我自己审题出错还是题目有歧义:我理解的是记录前八条错误数据,当遇到第九个错误数据时整个程序结束,然后排序,输出;但是,我根据期望的输出数据发现,题意是,记录全部错误数据,然后按降序排序,输出前八个.......差的不是一点点,坑死我了;
2.OJ在输出“你的输出”时,只输出到了和答案不同的第一个,后面的就不输出了,弄的我很难受,一看个数不对,还以为我哪里出现重大bug了...结果不是;

var result = [];
while (line = readline()) {
    var readline1 = line.split(' ');
    var temp = readline1[0].split('\\');
    var filename = temp[temp.length - 1],
        codeNum = readline1[1];
    var hasFlag =false;

    for(let i=0;i<result.length;i++){
        if(result[i][0] == filename && result[i][1] == codeNum){
            result[i][2] +=1;
            hasFlag =true;
            break;
        }
    }
    if(!hasFlag){
        result.push([filename,codeNum,1]);
    }
}
// 排序
bSort(result);
// 截取+输出
var len = result.length;
if(len >8){
    len = 8;
}
for(let i=0;i<len;i++){
    result[i][0] =result[i][0].substr(-16);
    print(result[i].join(' '));
}

// 冒泡,稳定排序
function bSort(arr) {
    var temp;
    for (let j = 0; j < arr.length - 1; j++) {
        for (let i = 0; i < arr.length - 1 - j; i++) {
            if (arr[i][2] < arr[i + 1][2]) {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
    }
    return arr;
}




编辑于 2020-03-08 00:35:07 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int i = 0;
        int falg = 0;
        String[] result = new String[8];
        int[] count = new int[8];
        while (sc.hasNextLine()) {
            String line = sc.nextLine();
            if (line.equals("")) break;
            line = line.substring(line.lastIndexOf("\\") + 1);
            String[] ss = line.split(" ");
            for (int j = 0; j < 8; j++) {
                if (count[j] != 0)
                    if (line.equals(result[j])) {
                        count[j]++;
                        falg = 1;
                    }
            }
            if (falg == 0) {
                result[i] = line;
                count[i] = 1;
                i++;
            }
        }
        for (int j = 0; j < 8; j++) {
            if (count[j] != 0)
                if (result[j].substring(0,result[j].indexOf(" ")).length() <= 16)
                    System.out.println(result[j] + " " + count[j]);
                else System.out.println(result[j].substring(result[j].length() - 16) + " " + count[j]);
        }
    }
}
//idea里输出正确这里输出顺序不一样,显示错误 
发表于 2020-02-12 23:10:47 回复(0)
import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        HashMap<String, Integer> logs = new HashMap<>();
        ArrayList<String> logs_list = new ArrayList<>();
        while(in.hasNextLine()) {
            String log = in.nextLine();
            String[] parsedLog = log.split("\\\\");
            String error = parsedLog[parsedLog.length - 1];
            if(logs.get(error) == null) {
                logs.put(error, 1);
                logs_list.add(error);
            }
            else{
                logs.put(error, logs.get(error) + 1);
            }
        }
        for(int i=0; i<8; i++) {
            int max = 0;
            String maxKey = "";
            for(String key : logs_list) {
                if(logs.get(key) > max){
                    max = logs.get(key);
                    maxKey = key;
                }
            }
            String filename = maxKey.split(" ")[0];
            if(filename.length() > 16) 
                filename = filename.substring(filename.length()-16);
            String finalKey = filename + " " + maxKey.split(" ")[1];
            System.out.println(finalKey + " " + logs.get(maxKey) + " ");
            logs_list.remove(maxKey);
        }
    }
}

发表于 2019-07-31 02:30:42 回复(0)