DreamJudge-1227-日志排序(精华)
1.题目介绍
Time Limit: 1000 ms
Memory Limit: 256 mb
有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录: “hs_10000_p”是计算任务的名称, “2007-01-17 19:22:53,315”是计算任务开始执行的时间“年-月-日 时:分:秒,毫秒”, “253.035(s)”是计算任务消耗的时间(以秒计) hs_10000_p 2007-01-17 19:22:53,315 253.035(s) 请你写一个程序,对日志中记录计算任务进行排序。 时间消耗少的计算任务排在前面,时间消耗多的计算任务排在后面。 如果两个计算任务消耗的时间相同,则将开始执行时间早的计算任务排在前面。
输入输出格式
输入描述:
日志中每个记录是一个字符串,每个字符串占一行。最后一行为空行,表示日志结束。日志中最多可能有10000条记录。
计算任务名称的长度不超过10,开始执行时间的格式是YYYY-MM-DD HH:MM:SS,MMM,消耗时间小数点后有三位数字。
计算任务名称与任务开始时间、消耗时间之间以一个或多个空格隔开,行首和行尾可能有多余的空格。
输出描述:
排序好的日志记录。每个记录的字符串各占一行。
输入的格式与输入保持一致,输入包括几个空格,你的输出中也应该包含同样多的空格。
输入输出样例
输入样例#:
hs_10000_p 2007-01-17 19:22:53,315 253.035(s)
hs_10001_p 2007-01-17 19:22:53,315 253.846(s)
hs_10002_m 2007-01-17 19:22:53,315 129.574(s)
hs_10002_p 2007-01-17 19:22:53,315 262.531(s)
hs_10003_m 2007-01-17 19:22:53,318 126.622(s)
hs_10003_p 2007-01-17 19:22:53,318 136.962(s)
hs_10005_m 2007-01-17 19:22:53,318 130.487(s)
hs_10005_p 2007-01-17 19:22:53,318 253.035(s)
hs_10006_m 2007-01-17 19:22:53,318 248.548(s)
hs_10006_p 2007-01-17 19:25:23,367 3146.827(s)
输出样例#:
hs_10003_m 2007-01-17 19:22:53,318 126.622(s)
hs_10002_m 2007-01-17 19:22:53,315 129.574(s)
hs_10005_m 2007-01-17 19:22:53,318 130.487(s)
hs_10003_p 2007-01-17 19:22:53,318 136.962(s)
hs_10006_m 2007-01-17 19:22:53,318 248.548(s)
hs_10000_p 2007-01-17 19:22:53,315 253.035(s)
hs_10005_p 2007-01-17 19:22:53,318 253.035(s)
hs_10001_p 2007-01-17 19:22:53,315 253.846(s)
hs_10002_p 2007-01-17 19:22:53,315 262.531(s)
hs_10006_p 2007-01-17 19:25:23,367 3146.827(s)
题目来源
北京大学机考题
2.题解
2.1 字符串处理(istringstream) 和 sort排序
思路
据我观察,这里有很多题解的完成率其实只有75%,这是为什么呢?因为他们都是将整个开始时间读作一个字符串,运行时间读作一个字符串,然后进行比较
这里有一个很坑的点,毫秒数和运行时间并不是字节序越小一定时间越早/短, 虽然前面的年月日时分秒由于格式固定这么说是没有错的;
但是对于毫秒数和运行时间,由于位数并不确定,像是字节序"40" > "355", 但是实际数值上上 40 < 355,这就会导致结果的错误
我这里采用了类 + sort排序, 进行了一个三层排序; 这里类中存一个整字符串,是因为拆了又合并,有两个东西位数不确定,不好确定如何拼接,干脆多存一个,直接输出了
这里字符串处理核心采用了 istringstream流,对于避开空格符和知道终止符的情况,是非常的好用,大家也可以了解一下
代码
#include <bits/stdc++.h>
using namespace std;
class Log {
public:
string content;
string name;
string startDate;
double ms;
double runtime;
Log(string content, string name, string date, double ms, double runtime)
: content(content), name(name), startDate(date), ms(ms), runtime(runtime) {}
// 比较函数
bool operator<(const Log& other) const {
if (runtime != other.runtime) {
return runtime < other.runtime;
} else if (startDate != other.startDate) {
return startDate < other.startDate;
}
return ms < other.ms;
}
};
int main() {
vector<Log> logs;
string input;
while (getline(cin, input) && !input.empty()) {
string name, spare, datetime, runtimeStr;
double ms, runtime;
istringstream iss(input);
// 读入程序名
iss >> name;
// 这里读入起始时间(不包括ms)
// 第一个参数:iss >> std::ws 跳跃空格; 第二个参数:读入后存储的参数; 第三个参数为读入终止符 ;
getline(iss >> std::ws, datetime, ',');
// ms需要单独处理, 像是 '40' > '355' 但是 40 < 355, 下面的运行时间同理
iss >> ms;
getline(iss >> std::ws, runtimeStr, '(');
runtime = stod(runtimeStr); // 转换为double类型
logs.emplace_back(input, name, datetime, ms, runtime);
}
// 使用 stable_sort 进行稳定排序, 默认采用Log的 < 运算比较符
stable_sort(logs.begin(), logs.end());
// 输出所有日志条目
for (const auto& log : logs) {
cout << log.content << endl;
}
return 0;
}