华为OD机考双机位C卷 - 运维日志排序 (Java & Python & JS & GO & C++ & C)
·
运维日志排序
2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型
点击查看华为 OD 机试真题完整目录:2026最新华为OD机试新系统卷 + 双机位C卷 真题题库目录|全覆盖题库 + 逐点算法考点详解
题目描述
[运维工程师]采集到某产品线网运行一天产生的日志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
说明
示例2
输入
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
说明
示例3
输入
2
22:41:08.023
22:41:08.23
输出
22:41:08.023
22:41:08.23
说明
说明 两个时间表示的时间相同,保持输入顺序
解题思路
解题思路分析
题目本质
这道题实质上是一个日志时间排序问题,核心在于如何正确解析不标准格式的时间字符串,并按时间顺序排序。
-
时间统一化处理
- 将各种格式的时间字符串转换为统一的数值单位(如毫秒总数)
- 这样可以直接通过数值比较来确定时间的先后顺序
-
解析时间字符串
- 使用正则表达式或字符串分割方法解析时间字符串
- 提取出小时、分钟、秒、毫秒四个部分
- 注意处理没有前导零的情况(如"1:1:1.1")
-
时间转换算法
- 将时间转换为统一单位:毫秒总数
- 计算公式:
(((小时 * 60) + 分钟) * 60 + 秒) * 1000 + 毫秒
-
排序实现
- 使用稳定排序算法(题目要求相同时间保持输入顺序)
- 基于转换后的时间数值进行排序
- 输出排序后的原始时间字符串
-
边界情况处理
- 确保正确处理可能的时间格式变体
- 处理日志数量范围(1≤n≤100000)
Java
import java.util.*;
import java.util.regex.*;
public class Main {
/* 将时间字符串转换为毫秒数 */
public static int convertToMillisecond(String timeStr) {
Pattern pattern = Pattern.compile("(\\d+):(\\d+):(\\d+).(\\d+)");
Matcher matcher = pattern.matcher(timeStr);
return matcher.find() ? ((Integer.parseInt(matcher.group(1)) * 60 + Integer.parseInt(matcher.group(2))) * 60 + Integer.parseInt(matcher.group(3))) * 1000 + Integer.parseInt(matcher.group(4)) : 0;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<String> logs = new ArrayList<>();
int n = scanner.nextInt();
scanner.nextLine(); // 忽略换行符
for (int i = 0; i < n; i++) {
String log = scanner.nextLine();
logs.add(log);
}
/* 日志排序 */
Collections.sort(logs, new Comparator<String>() {
public int compare(String log1, String log2) {
int time1 = convertToMillisecond(log1);
int time2 = convertToMillisecond(log2);
return time1 - time2;
}
});
for (String log : logs) {
System.out.println(log);
}
}
}
Python
import re
def convertToMillisecond(timeStr):
hour, minute, second, millisecond = map(int, re.findall(r'\d+', timeStr))
return hour * 60 * 60 * 1000 + minute * 60 * 1000 + second * 1000 + millisecond
logs = []
n = int(input())
for i in range(n):
log = input()
logs.append(log)
# 日志排序
logs.sort(key=lambda log: convertToMillisecond(log))
for log in logs:
print(log)
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const logs = [];
let n;
rl.on('line', (input) => {
if (!n) {
n = parseInt(input);
} else {
logs.push(input);
}
if (logs.length === n) {
/* 日志排序 */
logs.sort((log1, log2) => {
const time1 = convertToMillisecond(log1);
const time2 = convertToMillisecond(log2);
return time1 < time2 ? -1 : 1;
});
for (const log of logs) {
console.log(log);
}
rl.close();
}
});
function convertToMillisecond(timeStr) {
const match = timeStr.match(/(\d+):(\d+):(\d+).(\d+)/);
return (parseInt(match[1]) * 3600000) + (parseInt(match[2]) * 60000) + (parseInt(match[3]) * 1000) + parseInt(match[4]);
}
C++
#include <iostream>
#include <vector>
#include <regex>
#include <algorithm>
using namespace std;
int convertToMillisecond(string timeStr) {
regex pattern("(\\d+):(\\d+):(\\d+).(\\d+)");
smatch matcher;
return regex_search(timeStr, matcher, pattern) ? ((stoi(matcher[1]) * 60 + stoi(matcher[2])) * 60 + stoi(matcher[3])) * 1000 + stoi(matcher[4]) : 0;
}
int main() {
vector<string> logs;
int n;
cin >> n;
cin.ignore(); // 忽略换行符
for (int i = 0; i < n; i++) {
string log;
getline(cin, log);
logs.push_back(log);
}
/* 日志排序 */
sort(logs.begin(), logs.end(), [](const string& log1, const string& log2) {
int time1 = convertToMillisecond(log1);
int time2 = convertToMillisecond(log2);
return time1 < time2;
});
for (const string& log : logs) {
cout << log << endl;
}
return 0;
}
GO
package main
import (
"bufio"
"fmt"
"os"
"regexp"
"sort"
"strconv"
)
// 将时间字符串转换为毫秒数
func convertToMillisecond(timeStr string) int {
pattern := regexp.MustCompile(`(\d+):(\d+):(\d+)\.(\d+)`)
matches := pattern.FindStringSubmatch(timeStr)
if len(matches) > 0 {
hours, _ := strconv.Atoi(matches[1])
minutes, _ := strconv.Atoi(matches[2])
seconds, _ := strconv.Atoi(matches[3])
milliseconds, _ := strconv.Atoi(matches[4])
return ((hours*60+minutes)*60+seconds)*1000 + milliseconds
}
return 0
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 读取日志条数
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
// 读取所有日志
logs := make([]string, n)
for i := 0; i < n; i++ {
scanner.Scan()
logs[i] = scanner.Text()
}
// 日志排序
sort.Slice(logs, func(i, j int) bool {
time1 := convertToMillisecond(logs[i])
time2 := convertToMillisecond(logs[j])
return time1 < time2
})
// 输出排序后的日志
for _, log := range logs {
fmt.Println(log)
}
}
C语言
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 将时间字符串转换为毫秒数 */
int convertToMillisecond(const char *timeStr) {
int hours = 0, minutes = 0, seconds = 0, milliseconds = 0;
sscanf(timeStr, "%d:%d:%d.%d", &hours, &minutes, &seconds, &milliseconds);
return ((hours * 60 + minutes) * 60 + seconds) * 1000 + milliseconds;
}
/* 比较函数,用于qsort */
int compare(const void *a, const void *b) {
const char **log1 = (const char **)a;
const char **log2 = (const char **)b;
int time1 = convertToMillisecond(*log1);
int time2 = convertToMillisecond(*log2);
return time1 - time2;
}
int main() {
int n;
scanf("%d", &n);
getchar(); // 忽略换行符
char **logs = (char **)malloc(n * sizeof(char *));
for (int i = 0; i < n; i++) {
logs[i] = (char *)malloc(50 * sizeof(char)); // 假设每个时间字符串长度不超过50
fgets(logs[i], 50, stdin);
// 去除fgets输入中的换行符
logs[i][strcspn(logs[i], "\n")] = '\0';
}
/* 对日志进行排序 */
qsort(logs, n, sizeof(char *), compare);
/* 输出排序后的日志 */
for (int i = 0; i < n; i++) {
printf("%s\n", logs[i]);
free(logs[i]); // 释放每个日志字符串的内存
}
free(logs); // 释放日志指针数组的内存
return 0;
}
完整用例
用例1
2
01:41:8.9
1:1:09.211
用例2
3
23:41:08.023
1:1:09.211
08:01:22.0
用例3
2
22:41:08.023
22:41:08.23
用例4
5
10:00:00.001
11:00:00.002
12:00:00.003
13:00:00.004
14:00:00.005
用例5
4
12:30:00.001
15:45:00.002
09:00:00.003
18:20:00.004
用例6
6
01:01:01.001
02:02:02.002
03:03:03.003
04:04:04.004
05:05:05.005
06:06:06.006
用例7
10
23:59:59.999
00:00:00.001
12:00:00.000
01:01:01.001
02:02:02.002
03:03:03.003
04:04:04.004
05:05:05.005
06:06:06.006
07:07:07.007
用例8
7
12:30:00.001
15:45:00.002
09:00:00.003
18:20:00.004
01:01:01.001
02:02:02.002
03:03:03.003
用例9
6
1:1:09.211
01:41:8.9
08:01:22.0
23:41:08.023
00:00:00.001
12:00:00.000
用例10
4
12:00:00.000
00:00:00.001
23:59:59.999
06:30:45.123
文章目录

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)