题目描述
运维工程师采集到某产品线网运行一天产生的日志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个时间。
输出描述
按时间升序排序之后的时间,如果有两个时间表示的时间相同,则保持输入顺序。
用例
输入 |
2 |
输出 |
1:1:09.211 01:41:8.9 |
说明 | 无 |
输入 |
3 |
输出 |
1:1:09.211 08:01:22.0 23:41:08.023 |
说明 | 无 |
输入 |
2 |
输出 |
22:41:08.023 22:41:08.23 |
说明 | 两个时间表示的时间相同,保持输入顺序 |
题目解析
排序日志时间用到的知识是:
- 将字符串时间中各要素提取出来(正则捕获组),然后计算出总毫秒数
- 根据Array.prototype.sort自定义排序策略,来算出的总毫秒数进行排序
2023.08.15 优化
将字符串时间中各要素提取出来,其实可以简单地按照 ":" 和 "." 进行分割,这里可以使用正则 [:.] ,作为分隔符。
2023.10.15
本题考试Java如果出现超时,则大概率是输入获取超时,可以考虑使用BufferedReader高效输入获取方式。
Java算法源码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] logs = new String[n];
for (int i = 0; i < n; i++) logs[i] = br.readLine();
Arrays.sort(logs, (a, b) -> Long.compare(convert(a), convert(b)));
System.out.println(String.join("n", logs));
}
public static long convert(String log) {
String[] tmp = log.split("[:.]");
long H = Long.parseLong(tmp[0]) * 60 * 60 * 1000;
long M = Long.parseLong(tmp[1]) * 60 * 1000;
long S = Long.parseLong(tmp[2]) * 1000;
long N = Long.parseLong(tmp[3]);
return H + M + S + N;
}
}
JS算法源码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
const n = parseInt(await readline());
const logs = [];
for (let i = 0; i < n; i++) {
logs.push(await readline());
}
logs.sort((a, b) => convert(a) - convert(b));
console.log(logs.join("n"));
})();
function convert(log) {
const [H, M, S, N] = log.split(/[:.]/);
return (
parseInt(H) * 60 * 60 * 1000 +
parseInt(M) * 60 * 1000 +
parseInt(S) * 1000 +
parseInt(N)
);
}
Python算法源码
# 输入获取
import re
n = int(input())
logs = [input() for _ in range(n)]
def convert(log):
tmp = re.split(r"[:.]", log)
H = int(tmp[0]) * 60 * 60 * 1000
M = int(tmp[1]) * 60 * 1000
S = int(tmp[2]) * 1000
N = int(tmp[3])
return H + M + S + N
# 算法入口
def getResult():
logs.sort(key=convert)
return "n".join(logs)
# 算法调用
print(getResult())
C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(const void *a, const void *b);
long convert(char *time);
// 依次是 小时转毫秒,分钟转毫秒,秒转毫秒, 毫秒转毫秒 的系数
int unit[] = {60 * 60 * 1000, 60 * 1000, 1000, 1};
int main() {
// 日志条数
int n;
scanf("%d", &n);
// 输入n个时间
char **times = (char **) malloc(sizeof(char *) * n);
for (int i = 0; i < n; i++) {
times[i] = (char *) malloc(sizeof(char) * 15);
scanf("%s", times[i]);
}
// 按时间升序排序, 如果有两个时间表示的时间相同,则保持输入顺序
qsort(times, n, sizeof(char *), cmp);
// 依次打印排序后时间
for (int i = 0; i < n; i++) {
printf("%sn", times[i]);
}
return 0;
}
int cmp(const void *a, const void *b) {
return convert(*(char **) a) - convert(*(char **) b);
}
// 时间字符串转毫秒数
long convert(char *time) {
// strtok会改变被操作的字符串,因此这里要对输入字符串拷贝一下
char tmp[20];
strcpy(tmp, time);
// 时间字符串对应的毫秒数
long mills = 0;
// unit的索引
int i = 0;
// 时间字符串按照 : 或 . 分割
char *token = strtok(tmp, ":.");
while (token != NULL) {
mills += atol(token) * unit[i++];
token = strtok(NULL, ":.");
}
return mills;
}
免责声明:
1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文
评论0