华为2016校园招聘上机笔试题_记录出错的代码所在的文件名称和行号

题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

这个程序,看似简单,实际上考了很多细节,我花了很多时间来做,不是被算法
难住,而是在细节上出了很多漏洞。整体要求很快就实现了,而一直报答案错误
,第一个原因,只能是8条记录以内,我全部输出;第二个原因,题目要求稳定排
序,我排出来了,却颠倒了关键字的顺序;第三个原因,我以为都OK了,却忘了
文件名16个字符的要求。三个原因我找了很久,我以为我是理解题目错误,实际
上就是忽略了细节,造成浪费了大量的时间。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
public class Main {
    static class EFile{
        public String name;
        public int line;
        public int num;
        public int order;
         
         
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + line;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
 
            EFile other = (EFile) obj;
            if (this == obj){ other.num++; return true;
            }
            if (getClass() != obj.getClass())
                return false;
             
            if (line != other.line){
                return false;
            }
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name)){
                return false;
            } other.num++;  return true;
        }
         
    }
    public static void main(String[] args){
        Set<EFile> set = new HashSet<EFile>();
        Scanner in = new Scanner(System.in);
        int j = 0;
        while (in.hasNext()) {
            String s = in.next();
            int line = in.nextInt();
            EFile file = new EFile();
            int bi = s.lastIndexOf("\\");
            file.name = s.substring(bi+1);
            file.line = line;
            if(set.add(file)){
                file.num++;
                file.order = j;
                j++;
            }
             
        }
        in.close();
        List<EFile> list = new ArrayList<EFile> (set);
        Comparator<EFile> cmp = new Comparator<EFile>() {
            @Override
            public int compare(EFile o1, EFile o2) {
                return o1.num - o2.num ==0 ?(o1.order-o2.order):(o2.num-o1.num);
            }
        };
        Collections.sort(list,cmp);
        StringBuffer sb = new StringBuffer();
         
        for(int i = 0; i < (list.size() > 8 ? 8 : list.size()); i ++){
            StringBuffer result;
            EFile eFile = list.get(i);
            if(eFile.name.length() > 16){
                result =new StringBuffer(eFile.name.substring(eFile.name.length() - 16, eFile.name.length()));
            }else{
                result =new StringBuffer(eFile.name);
            }
            result.append(" ").append(eFile.line).append(" ").append(eFile.num);
            System.out.println(result.toString());
        }
         
 
    }
}
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        //创建接受键盘录入对象
        Scanner cin = new Scanner(System.in);
        // 接受文件名称或者文件路径
        String file = null;
        // 获取文件路径 最后一个“\” 下标索引
        int lastIndex = 0;
        // 获取文件名称
        // 接受错误出现的行号
        int errorLine = 0;
        // 创建一个HashMap<ErrLog>
        HashMap<String, ErrLog> hashMap = new HashMap<String, ErrLog>();
        ErrLog errLog = null;
        String key = null;
        StringBuilder sbBuilder = new StringBuilder();
        while (cin.hasNext()) {
            // 第一个参数为文件名称或文件路径
            file = cin.next();
            // 获取错误行号
            errorLine = cin.nextInt();
            // 获取最后一个'\'的索引
            lastIndex = file.lastIndexOf('\\');
            // 如果没有找到说明不是路径,直接返回文件名
            // 是路径 就截取\后面的字符串作为文件名
            sbBuilder
                .append(lastIndex < 0 ? file : file.substring(lastIndex + 1))
                .append(" ").append(errorLine);
            key = sbBuilder.toString();
            sbBuilder.setLength(0);
            // 将错误记录添加进hashMap 中
            errLog = hashMap.get(key);
            if (errLog == null) {
                // 如果不存在,new 一个并添加进去
                hashMap.put(key, new ErrLog(key, 1));
            } else errLog.size++; //存在,就将错误次数累加
        }
        cin.close();
        // ----------以上就是统计错误信息,下面是取值------------------
        ArrayList<ErrLog> list = new ArrayList<ErrLog>(hashMap.values());
        // 根据 错误次数比较,将错误次数多的放前面,如果错误次数一致,将出现顺序早的放到前面 进行排序
        Comparator<ErrLog> cmp = new Comparator<ErrLog>() {
            @Override
            public int compare(ErrLog o1, ErrLog o2) {
                return o2.size - o1.size == 0 ? (o1.queueMark - o2.queueMark)
                    : o2.size - o1.size;
            }
        };
        Collections.sort(list, cmp);
        // 取出前8个,并输出
        int lens = 8 > list.size() ? list.size() : 8;
        for (int i = 0; i < lens; i++) {
            //这里文件名如果大于16位 还需要截取文件名16位 + 行号 输出
            errLog = list.get(i);
            //这样就获取到了分界符' '的索引了,然后往前推16位就是我们要输出的文件名了
            lastIndex = errLog.name.lastIndexOf(" ");
            lastIndex = lastIndex - 16 < 0 ? 0 : lastIndex - 16;
            // 获取文件名并输出
            System.out.println((lastIndex == 0 ? errLog.name : errLog.name
                .substring(lastIndex)) + " " + errLog.size);
        }
    }
}
 
class ErrLog {
    // 此类并不标准,仅方便此题目实现而已
    static int mark; //辅助实现字段queueMark按出现顺序自增
    String name;//fileName 存储错误的文件名称,由完整的文件名,与错误行号组成。
    int queueMark; // 标记出现的顺序
    int size; // 统计出现错误的次数
 
    public ErrLog(String name, int size){
        super();
        this.name = name;
        this.queueMark = mark++;
        this.size = size;
    }
}
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

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());
        }
    }
}
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

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);
        }
    }
}
链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

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());
        }
    }
}

我和你写的一样,但是因为同一个文件名和行号被put进去多次,而linkedhashmap里面就是最近一次插入的相对顺序,而不是第一次插入的相对顺序,所以是不对的

可以改参数

链接:https://www.nowcoder.com/questionTerminal/67df1d7889cf4c529576383c2e647c48
来源:牛客网

package nowcoder.record;

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

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        List list = new ArrayList();
        while (sc.hasNext()) {

            String line = sc.nextLine();
            String[] arr = line.split(" ");
            String path = arr[0]; // 路径
            int lineNum = Integer.valueOf(arr[1]); // 行号
            String fileName = path;
            if (path.contains("\\")) {
                fileName = path.substring(path.lastIndexOf("\\") + 1); // 截取文件名
            }
            String key = fileName + " " + lineNum;
            Iterator it = list.iterator();
            boolean flag = false;
            while (it.hasNext()) {
                Model model = it.next();
                if (model.getKey().equals(key)) {
                    model.setCount(model.getCount() + 1);
                    flag = true;
                }
            }
            if (!flag) {
                Model model = new Main().new Model(key, 1);
                list.add(model);
            }
        }
        // System.out.println("origin:");
        // for (Model model : list) {
        // System.out.println(model.getKey() + " " + model.getCount());
        // }
        // 下面排序并輸出
        Collections.sort(list, new Comparator() {

            public int compare(Model o1, Model o2) {
                // TODO Auto-generated method stub
                return o2.getCount() - o1.getCount();
            }
        });
        // System.out.println("last:");

        //超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
        //最多输出8条记录
        for (int i = 0; i < list.size() && i < 8; i++) {
            Model model = list.get(i);
            String temp = model.getKey();
            String[] arrs = temp.split(" ");
            String name = arrs[0];
            int c = Integer.valueOf(arrs[1]);

            name = name.length() > 16 ? name.substring(name.length() - 16)
                    : name;
            temp = name + " " + c;
            System.out.println(temp + " " + model.getCount());
        }
    }

    class Model {

        public Model(String key, int count) {
            super();
            this.key = key;
            this.count = count;
        }

        String key;
        int count;

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public int getCount() {
            return count;
        }

        public void setCount(int count) {
            this.count = count;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值