华为技术二面手撕代码-20231221

刷题记录
------分割线------
华为技术二面手撕代码


文章目录

  • 前言
  • 一、题目内容
  • 二、自己的思路
  • 三、自己的代码实现
  • 总结


前言

想到什么写什么:

技术二面的前一天,准备了项目上的问答,对算法其实自己挺有信心的,结果睡觉没睡好,导致下午才起床,然后天又冷,为了保持清醒就没开空调,结果脑子就冻着了,半个小时内居然没写完,主要原因是1.自己审题不清,没看清题目就开始写;2.自己之前都是先在草稿纸上写出思路,再开始写代码,但今天却不知是紧张还是手冻,没先在纸上写出逻辑,而是一边写一边想,这样浪费了大量的时间,效率不如纸上草画的快。


提示:以下是本篇文章正文内容,下面案例可供参考

一、题目内容

给定n条日志,用英文分号分隔的字符串:
2020-02-01|192.168.1.121|/login.do|success;2020-02-02|192.168.001.121|/login.do|success;2020-02-03|192.168.1.122|/login.do|fail;2020-02-04|192.168.01.123|/login_to.do|success;2020-02-04|192.168.1.124|/login.do|success
日志格式分为几部分,说明如下:
1: 日期yyyy-mm-dd,保证日期都在一个月内
2: ip:.分格式,保证为合法ip(1.1.1.1和1.001.01.1为同一ip)
3: 访问url: 仅由字母、/ 、.、_、数字 组成
4: 访问是否成功,只有success fail 2种结果
求统计日活和月活:
日活:每天不同ip数访问/login.do且结果为success的数量
月活:每月不同ip数访问/login.do且结果为success的数量
输出 32个数:
第一个表示月活,后面31个数表示每天的日活
2 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

二、自己的思路

	将字符串通过";"解析成每条日志,然后对每条日志对"|"进行解析成数组,这里用split的时候要匹配|需要写成\\|,同理于".",对数组的最后两个数据进行/login.do和success匹配,满足条件的情况,在进行逻辑判断。
	其中数组第二个数据是ip,取出来,进行多余0的过滤,可以用.进行split,然后每个String转换成int再转换回来拼成一个String,这时用一个set来记录这个String,add成功,则月日志数据+1。
	然后定义一个长度为31的int数组,用一个>map来记录每一天的日志数据,然后在最开始的数组中取出日期,因为是默认同一个月,所以只需要取最后两位,为日期,同时为了匹配对应的int数组Index,将日期减1,先判断map是否包含这个日期key,不包含,就新建一个set,存入map中,同时对int[day]+1;如果包含这个日期key,则取出这个set,往里面添加ip,添加成功,则对应的int[day]+1,同时把set重新存入到对应map的k-v中;添加失败则直接进行下一个判断。
	最后全部输出即可。

三、自己的代码实现

public class Main {

public static  void  main(String[] args){
    Main aa = new Main();
    aa.total("2020-02-01|192.168.1.121|/login.do|success;2020-02-02|192.168.001.121|/login.do|success;2020-02-03|192.168.1.122|/login.do|fail;2020-02-04|192.168.01.123|/login_to.do|success;2020-02-04|192.168.1.124|/login.do|success");
}

public int[] days = new int[31];
public Set monthSet = new HashSet<>();
public Map> dayMap = new HashMap<>();

public void total(String str){
    // 月活总数
    int monthCount = 0;
    String[] monthArray = str.split(";");

    for(String dayStr : monthArray){
        String[] dayArray = dayStr.split("\\|");
        int length = dayArray.length;
        //满足条件再进行统计
        if(dayArray[length-1].equals("success")&&dayArray[length-2].equals("/login.do")){
            //排重
            int day = Integer.valueOf(dayArray[0].substring(dayArray[0].length()-2))-1;
            //ip去0
            String ip = dayArray[1];
            StringBuilder newIp = new StringBuilder();

            for(String c:ip.split("\\.")){
                newIp.append(Integer.valueOf(c)).append(".");
            }
            ip = newIp.toString();
            // 针对月来说
            if(monthSet.add(ip)){
                monthCount++;
            }
            // 针对日来说
            if(dayMap.containsKey(day)){
                Set set = dayMap.get(day);
                if(set.add(ip)){
                    dayMap.put(day,set);
                    days[day]++;
                }
            }else{
                Set daySet = new HashSet<>();
                daySet.add(ip);
                dayMap.put(day,daySet);
                days[day]++;
            }
        }
    }

    System.out.print(monthCount);
    for(int k:days){
        System.out.print(" "+k);
    }
}

}

总结

在面试结束之前,我还是表达了一下代码的思路,虽然面试官说机试我400满分过,这只是一部分,但我还是对自己不满意,在面试结束后,大概花了五分钟就搞定了,所以还是要保持好自己面试前的状态,冬天只是让自己的身体活络起来,太僵硬的手也的确影响思维的发挥,当然还有一点紧张,这点需要提升,此文仅做纪念。

你可能感兴趣的:(java,算法)