【华为OD机试】运维日志排序

题目描述:

运维工程师采集到某产品线网运行一天产生的日志n条,现需根据日志时间先后顺序对日志进行排序,日志时间格式为H:M:S.N。

H表示小时(0~23)

M表示分钟(0~59)

S表示秒(0~59)

N表示毫秒(0~999)

时间可能并没有补全,也就是说,01:01:01.001也可能表示为1:1:1.1。

输入描述

第一行输入一个整数n表示日志条数,1<=n<=100000,接下来n行输入n个时间。

输出描述:

按时间升序排序之后的时间,如果有两个时间表示的时间相同,则保持输入顺序。

示例 1**:**

输入

2

01:41:8.9

1:1:09.211

输出:

1:1:09.211

01:41:8.9
输入:

3

23:41:08.023

1:1:09.211

08:01:22.0

输出:

1:1:09.211

08:01:22.0

23:41:08.023
输入:

2

22:41:08.023

22:41:08.23

输出:

22:41:08.023

22:41:08.23

代码思路:

方法一

java 复制代码
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = Integer.parseInt(in.nextLine());  // 读取日志条数
        // 存储日志时间和原始输入顺序
        List<LogTime> logs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            String timeStr = in.nextLine();
            logs.add(new LogTime(timeStr, i));  // 保存原始顺序用于稳定排序
        }
        // 自定义排序:按时间升序,时间相同时按输入顺序
        logs.sort((a, b) -> {
            // 比较小时
            if (a.hour != b.hour) {
                return Integer.compare(a.hour, b.hour);
            }
            // 比较分钟
            if (a.minute != b.minute) {
                return Integer.compare(a.minute, b.minute);
            }
            // 比较秒
            if (a.second != b.second) {
                return Integer.compare(a.second, b.second);
            }
            // 比较毫秒
            if (a.millisecond != b.millisecond) {
                return Integer.compare(a.millisecond, b.millisecond);
            }
            // 时间完全相同时,按输入顺序排序
            return Integer.compare(a.originalOrder, b.originalOrder);
        });

        // 输出排序后的时间
        for (LogTime log : logs) {
            System.out.println(log.originalString);
        }
    }
    
    static class LogTime {
        String originalString;  // 原始字符串表示
        int hour;               // 小时
        int minute;             // 分钟
        int second;             // 秒
        int millisecond;        // 毫秒
        int originalOrder;      // 原始输入顺序
        
        public LogTime(String timeStr, int order) {
            this.originalString = timeStr;
            this.originalOrder = order;
            parseTime(timeStr);
        }
        
        private void parseTime(String timeStr) {
            // 分割为小时、分钟、秒和毫秒部分
            String[] parts = timeStr.split(":");
            // 解析小时
            this.hour = Integer.parseInt(parts[0]);
            // 解析分钟
            this.minute = Integer.parseInt(parts[1]);
            // 秒和毫秒部分
            String[] secAndMs = parts[2].split("\\.");
            this.second = Integer.parseInt(secAndMs[0]);
            // 毫秒部分:可能没有补全,如".1"表示100毫秒
            if (secAndMs.length > 1) {
                String msStr = secAndMs[1];
                // 根据位数补全毫秒
                if (msStr.length() == 1) {
                    this.millisecond = Integer.parseInt(msStr) * 100;
                } else if (msStr.length() == 2) {
                    this.millisecond = Integer.parseInt(msStr) * 10;
                } else {
                    // 取前三位作为毫秒
                    if (msStr.length() > 3) {
                        msStr = msStr.substring(0, 3);
                    }
                    this.millisecond = Integer.parseInt(msStr);
                }
            } else {
                this.millisecond = 0;  // 没有毫秒部分
            }
        }
    }
}

方法二

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt();
        in.nextLine();
        String[] st = new String[n];
        for(int i=0;i<n;i++){
            st[i]=in.nextLine();
        }
        ascSort(st);
    }
    public static void ascSort(String[] st){
        HashMap<Integer[],List<String> > map =new HashMap<>();
        Set<Integer[]> set =new HashSet<>();
        for(int i=0;i<st.length;i++){
            Integer[] nums =new Integer[4];
            String[] cur_s = st[i].split(":");
            nums[0] = Integer.parseInt(cur_s[0]);
            nums[1]=Integer.parseInt(cur_s[1]);
            String[] ms=cur_s[2].split("\\."); //秒和毫秒
            nums[2]=Integer.parseInt(ms[0]);
            nums[3]=Integer.parseInt(ms[1]);
            set.add(nums);
            if(map.containsKey(nums)){
                map.get(nums).add(st[i]);
            }else{
                List<String> l1 = new ArrayList<>();
                l1.add(st[i]);
                map.put(nums,l1);
            }
        }
        List<Integer[]> list=new ArrayList<>(set);
        list.sort((a,b)->{
            for(int i=0;i<a.length;i++){
                if(a[i]!=b[i]){
                    return Integer.compare(a[i],b[i]);
                }
            }
            return 0;
        });
        for(Integer[] nums:list){
            List<String> l1=map.get(nums);
            for(String s:l1){
                System.out.println(s);
            }
        }
    }
}
相关推荐
萧曵 丶18 小时前
Java 泛型详解
java·开发语言·泛型
独断万古他化18 小时前
【Spring Web MVC 入门实战】实战三部曲由易到难:加法计算器 + 用户登录 + 留言板全流程实现
java·后端·spring·mvc
学后端的小萝卜头18 小时前
如何通过HTTP Range请求分段获取OSS资源(下载篇)
java·网络·http
造夢先森18 小时前
常见数据结构及算法
数据结构·算法·leetcode·贪心算法·动态规划
迷途的小子18 小时前
go-gin binding 标签详解
java·golang·gin
机灵猫19 小时前
守卫系统的最后一道防线:深入 Sentinel 限流降级与熔断机制(对比 Hystrix)
java·hystrix·sentinel
教练、我想打篮球19 小时前
124 记一次 大模型无限输出 “--“ 导致的短时间频繁 ygc
java·flow·ygc
while(1){yan}19 小时前
Spring日志
java·后端·spring
小肖爱笑不爱笑19 小时前
Maven
java·log4j·maven
FreeBuf_19 小时前
攻击者伪造Jackson JSON库入侵Maven中央仓库
java·json·maven