华为OD题目: 异常的打卡记录

异常的打卡记录
描述

考勤记录是分析和考核职工工作时间利用情况的原始依据,也是计算职工工资的原始依据。

为了正确地计算职工工资和监督工资基金使用情况,公司决定对员工的收集打卡记录进行异常排查。

如果出现以下两种情况,则认为打卡异常:

  1. 实际设备号与注册设备号不一样。

  2. 或者,同一个员工的两个打卡记录的时间小于60分钟并且打卡距离超过5km。

给定打卡记录的字符串数组clockRecord(每个打卡记录组成为:工号,时间(分钟),打卡距离(km),实际设备号,注册设备号),返回其中异常的打卡记录(按输入顺序输出)

输入描述

第一行输入为N,表示打卡记录数;

之后的N行为打卡记录,每一行为一条打卡记录。

输出描述

输出为异常的打卡记录。

备注

  1. clockRecord长度 <= 1000;
  2. clockRecords[i]格式:{id}, {time}, {distance}, {actualDeviceNumber}, {registeredDeviceNumber};
  3. id由6位数字组成;
  4. time由整数组成,范围为0~1000;
  5. distance由整数组成,范围为0~100;
  6. actualDeviceNumber与registeredDeviceNumber由四位大写字母组成。
    示例1
输入:2
     100000,10,1,ABCD,ABCD
     100000,50,10,ABCD,ABCD
输出:100000,10,1,ABCD,ABCD;100000,50,10,ABCD,ABCD
说明:第一条记录是异常的,因为第二条与它的间隔不超过60分钟但是打卡距离超过5km,同理第二条记录也是异常的。

示例2

输入:2
     100000,10,1,ABCD,ABCD
     100000,80,10,ABCE,ABCD
输出:100000,80,10,ABCE,ABCD
说明:第二条记录的注册设备号与打卡设备号不一致,所以是异常记录。

示例3

输入:2
     100000,10,1,ABCD,ABCD
     100001,80,10,ABCE,ABCE
输出:null
说明:无异常打卡记录,所以返回null。

```java
package com.darling.boot.order.od.od14;

import java.util.*;


//
//如果出现以下两种情况,则认为打卡异常:
//* 实际设备号与注册设备号不一样。
//* 或者,同一个员工的两个打卡记录的时间小于60分钟并且打卡距离超过5km。

/**
 * 解题思路:
 * 这道题记得是 返回其中异常的打卡记录(按输入顺序输出),
 * 按顺序的话,必须记住对应的下标,存放的时候,就不能用单纯的set,list等等,就得用到map了
 * 然后异常的结果集 exceptionMap必须按照value进行升序排序后的放入list里面
 * 然后输出结果
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String numStr = sc.nextLine();
        int n = Integer.parseInt(numStr);

        Map<String, Integer> exceptionMap = new HashMap<>();
        Map<String, Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            String line = sc.nextLine();

            String[] curStrings = line.split(",");
            int curTime = Integer.parseInt(curStrings[1]);
            int curDistance = Integer.parseInt(curStrings[2]);
            if (!curStrings[3].equals(curStrings[4])) {
                exceptionMap.put(line, i);
            }
            //和前面已有的对比,看能不能再找出异常的来
            for (String str: map.keySet()) {
                String[] split = str.split(",");
                int time = Math.abs(Integer.parseInt(split[1]) - curTime);
                int distance = Math.abs(Integer.parseInt(split[2]) - curDistance);
                if (time < 60 && distance > 5) {
                    exceptionMap.put(str, map.get(str));
                    exceptionMap.put(line, i);
                }
            }
            map.put(line, i);
        }
        if (exceptionMap.size() == 0) {
            System.out.println("null");
            return;
        }
        List<Map.Entry<String, Integer>> list = new ArrayList<>(exceptionMap.entrySet());
        list.sort((a1, a2) -> a1.getValue() - a2.getValue());
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Integer> entry : list) {
            sb.append(entry.getKey()).append(";");
        }
        //删掉最后一个 “;”
        sb.deleteCharAt(sb.length() - 1);
        System.out.println(sb);

    }


}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值