首页 > 试题广场 >

日志排序

[编程题]日志排序
  • 热度指数:12336 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录: “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,消耗时间小数点后有三位数字。
计算任务名称与任务开始时间、消耗时间之间以一个或多个空格隔开,行首和行尾可能有多余的空格。


输出描述:
排序好的日志记录。每个记录的字符串各占一行。
输入的格式与输入保持一致,输入包括几个空格,你的输出中也应该包含同样多的空格。
示例1

输入

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)
//要说这题有什么帮助的话,那就是学到了“sscanf的”函数的用法,贼好用!
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
struct recode{
    char s[100];
    string name;//名字实际上用不到
    string start;
    double time;
}r[10000];
bool cmp(recode a,recode b){
    if(a.time!=b.time)return a.time<b.time;
    return a.start<b.start;
}
int main(){
    int size=0;
    char name[15],start1[15],start2[15];
    double time;
    while(gets(r[size].s)&&strlen(r[size].s)!=0){
        sscanf(r[size].s,"%s%s%s%lf",name,start1,start2,&r[size].time);
        //r[size].name=name;//名字反正也用不到,不赋值也行
        r[size++].start=string (start1)+string(start2);
    }
    sort(r,r+size,cmp);
    for(int i=0;i<size;i++)
        printf("%s\n",r[i].s);
}

编辑于 2018-02-19 21:32:22 回复(6)
//参考“假面英雄暗律”的代码,将会报错的gets改成了c++的getline,sscanf输入也改成了istringstream;
#include<iostream>
#include<cstdio>
#include<sstream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

struct program{
    string s;
    string name;
    string start;
    double time;
}r[10000];
bool cmp(program a, program b){
    if(a.time != b.time) return a.time < b.time;
    return a.start < b.start;
}
int main(){
    int size = 0;
    string name, start1, start2;
    double time;
    while(getline(cin, r[size].s) && r[size].s.size() != 0){
        istringstream stream(r[size].s);
        stream >> name;
        stream >> start1;
        stream >> start2;
        stream >> r[size].time;
        r[size++].start = start1 + start2;
    }
    sort(r, r + size, cmp);
    for(int i = 0; i < size; i++){
        cout << r[i].s << endl;
    }
    return 0;
}

发表于 2021-03-12 20:00:25 回复(0)
/*
    考察字符串的划分和排序
    我用的是istringstream 对读入的字符串进行划分,但是时间会比sscanf慢
    毕竟io还是c快的多
*/

#include <bits/stdc++.h>
using namespace std;
struct Log{
	string s; // 保存原本的数据
	string name; // 名字
	double time; // 记录时间
}logs[10000];
bool cmp(Log a,Log b){ // 排序函数
	if(a.time == b.time) return a.name<b.name;
	else return a.time<b.time;
}
int main(){
	int i = 0;
	while(getline(cin,logs[i].s)){ // 读入一行
		istringstream is(logs[i].s); // 绑定s,对读入的数据进行划分
		string str1,str2,str3;
		//hs_10000_p   2007-01-17 19:22:53,315     253.035(s)
		is>>str1>>str2>>str3>>logs[i].time;
		logs[i].name = str2+str3;
		i++;
	}
	sort(logs,logs+i,cmp); // 排序
	for(int j=0;j<i;j++){
		cout<<logs[j].s<<endl;
	}
}

发表于 2020-03-25 18:00:26 回复(0)
//============================================================================
// Name        : 2017-05-22-06.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
using namespace std;

#define eps 1e-8
#define More(a,b) ((a)-(b)>eps)
#define Less(a,b) ((b)-(a)>eps)

struct m_log{
	string raw;
	string name;
	string date1;
	string date2;
	string time;
}logs[10001];

bool cmp(m_log log1,m_log log2){
	if(More(stof(log1.time.substr(0,log1.time.length()-3)),stof(log2.time.substr(0,log2.time.length()-3)))){
		return false;
	}else if(Less(stof(log1.time.substr(0,log1.time.length()-3)),stof(log2.time.substr(0,log2.time.length()-3)))){
		return true;
	}else if(log1.date1>log2.date1){
		return false;
	}else if(log1.date1<log2.date1){
		return true;
	}else if(log1.date2>log2.date2){
		return false;
	}else{
		return true;
	}
}

int main() {
	string in;
	int cnt=0;
	while(getline(cin,in)&&in.length()!=0){
		logs[cnt].raw = in;
		istringstream isinput;
		isinput.str(in);
		isinput>>logs[cnt].name>>logs[cnt].date1>>logs[cnt].date2>>logs[cnt].time;
		cnt++;
	}
//	cout<<1<<endl;
//	log log1 = logs[0];
//	cout<<log1.time.substr(0,log1.time.length()-3);
	sort(logs,logs+cnt,cmp);
	for(int i=0;i<cnt;i++){
		cout<<logs[i].raw<<endl;
	}
	return 0;
}


发表于 2017-05-22 11:11:52 回复(0)
用一下C里面的sscanf提取对应格式数据就好了,定义struct的时候记得加一个描述量,值为输入的字符串。
#include<stdio.h>
#include <cstdio>
#include<stdlib.h>
#include <cstdlib>
#include<iostream>
#include<string>
#include<string.h>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
//学习***canf
typedef struct{
    char description[1000];//整个描述
    char name[11];//描述中的任务名
    char start_date[20];//描述中的开始日期
    char start_time[20];//描述中的开始时间
    double time;//描述中的任务消耗时间
}Task;

bool compare(Task a,Task b){
    if(a.time!=b.time)
        return a.time<b.time;
    else if(strcmp(a.start_date, b.start_date)!=0)
        return (strcmp(a.start_date, b.start_date)<0);
    else if(strcmp(a.start_time, b.start_time)!=0)
        return (strcmp(a.start_time, b.start_time)<0);
    return false;
}

int main(){
    vector<Task> task(10000);
    string s;
    int count=0;
    while (getline(cin, s)&&s.length()!=0) {
        //字符串转化为char数组
        for (int i=0; i<s.length(); ++i) {
            task[count].description[i]=s[i];
        }
        //添加结束符号
        task[count].description[s.length()]='\0';
        //提取对应信息
        sscanf(task[count].description, "%s %s %s %lf",task[count].name,task[count].start_date,task[count].start_time,&task[count].time);
        s="";
        ++count;
    }
    sort(task.begin(), task.begin()+count, compare);
    //输出对应信息
    for (int i=0; i<count; ++i) {
        cout<<task[i].description<<endl;
    }
    return 0;
}



发表于 2021-03-16 09:50:57 回复(0)
#include <iostream>
#include <vector>
#include <string>
#include <regex>
#include <algorithm>

using namespace std;

class Log {
public:
	string myLog;
	string start;
	double consumption;

	Log(string myLog, string start, double consumption) {
		this->myLog = myLog;
		this->start = start;
		this->consumption = consumption;
	}
};

bool cmp(Log l1, Log l2) {
	if (l1.consumption != l2.consumption) {
		return l1.consumption < l2.consumption;
	}
	else {
		return l1.start.compare(l2.start) == -1;
	}
}

int main() {
	string str;
	smatch start_m, consumption_m;
	regex start_reg("(\\d){4}-(\\d){2}-(\\d){2}(\\s)+(\\d){2}:(\\d){2}:(\\d){2},(\\d){3}");
	regex consumption_reg("(\\d)+(\\\.)(\\d)+");
	vector<Log> log;
	while (getline(cin, str)) {
		if (str.empty()) {
			break;
		}
		bool found1 = regex_search(str, start_m, start_reg);
		bool found2 = regex_search(str, consumption_m, consumption_reg);
		if (found1 && found2) {
			log.emplace_back(Log(str, start_m[0].str(), atof(consumption_m[0].str().c_str())));
		}
	}
	stable_sort(log.begin(), log.end(), cmp);
	for (auto l : log) {
		cout << l.myLog << endl;
	}
	return 0;
}

发表于 2021-03-13 17:57:20 回复(0)
明明是一致的,却AC不了,就很奇怪
#include <bits/stdc++.h>

using namespace std;

struct logRecord
{
    char id[11];
    char date[11];
    char time[13];
    char cost[12];
}logs[10001];

bool compare(logRecord a, logRecord b);

int main()
{
    int cnt = 0;
    while(cin >> logs[cnt].id >> logs[cnt].date >> logs[cnt].time >> logs[cnt].cost)
    {
        cnt++;
    }
    stable_sort(logs,logs + cnt,compare);
    for (int i = 0; i < cnt; ++i)
    {
        cout << logs[i].id <<"   " << logs[i].date <<" " << logs[i].time <<"   " << logs[i].cost << endl;
    }
    return 0;
}
bool compare(logRecord a, logRecord b)
{
    int ret = -1;
    ret = strcmp(a.cost,b.cost);
    if(ret > 0)
        return false;
    else if(ret < 0)
        return true;
    else
    {
        ret = strcmp(a.date,b.date);
        if(ret > 0)
            return false;
        else if(ret < 0)
            return true;
        else
        {
            ret = strcmp(a.time,b.time);
            if(ret > 0)
                return false;
            else
                return true;
        }
    }
}

发表于 2021-03-03 10:41:08 回复(2)
//1.把后面要排序的数据首先装到一个数组
//2.找到最小的位置把原数据输出
#include<stdio.h>
(737)#include<string.h>
int main()
{
    char a[10000][100],b[10000][100];
    int n=0,i,j,k;
    //输入
    while(gets(a[n])&&strlen(a[n])) n++;
    for(i=0;i<n;i++)//行
    {
        for(j=strlen(a[i])-1;a[i][j]!='\0';j--)
        {
            if(a[i][j]==' ')
            {
                strcpy(b[i],a[i]+j+1);//把数据存到b
                break;
            }
        }
    }
    //找最小的位置
    int minindex=0;
    for(i=0;i<n;i++)
    {
        char min[100]="9999999";
        for(j=0;j<n;j++)
        {
            if(strcmp(b[j],min)<0)
            {
                strcpy(min,b[j]);
                minindex=j;
            }
        }
        printf("%s\n",a[minindex]);
        strcpy(b[minindex],"9999999");//把最小的那个位置更改成 最大的避免再次判断他
    }
}

发表于 2020-04-18 16:12:08 回复(3)
Java 清晰解法
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<String> list = new ArrayList<>();
        while (scanner.hasNext()){
            String line = scanner.nextLine();
            list.add(line);
        }
        list.sort(Comparator.comparing(Main::getTime));
        for (String s : list) System.out.println(s);
    }
    
    static Double getTime(String s){
        String[] s1 = s.split("\\s+");
        String ss = s1[3].substring(0, s1[3].indexOf("(s)"));
        return  Double.parseDouble(ss);
    }
}


发表于 2020-03-20 18:30:19 回复(0)
无注释版
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
struct E{
    char name[11]; //不超过10+1
    char date[11]; //4+1+2+1+2 + 1 = 11
    char time[13]; //2+1+2+1+2+1+3 + 1=13
    char cost[20]; //时间不是固定
    int pointer;
}record[10001];
int cmp(const void *p1, const void *p2){
    struct E * record1 = (struct E *)p1;
    struct E * record2 = (struct E *)p2;
    float cost1 = atof(strtok(record1->cost,"("));
    float cost2 = atof(strtok(record2->cost,"("));
    float res = cost1-cost2;
    int result = (cost1-cost2) * 10000.0;
    if(cost1 != cost2) return result;
    if(strcmp(record1->date,record2->date)) return strcmp(record1->date,record2->date);
    return strcmp(record1->time,record2->time);
}
char diary[10001][100];
int main(){
    int size,i = 0;
    i = 1;
    scanf("%[^\n]%*c",diary[0]);
    do{
        sscanf(diary[i-1],"%s%s%s%s", record[i-1].name, record[i-1].date, record[i-1].time, record[i-1].cost);
        record[i].pointer = i;
        scanf("%[^\n]%*c",diary[i]);
    }while(strlen(diary[i++]) != 0);
    size = i-1;//size之前写得等于i,然后就越界了。。。。
    qsort(record, size, sizeof(record[0]), cmp);
    for(i = 0; i < size; i++){
        printf("%s\n",diary[record[i].pointer]);
    }
    return 0;
}
加注释及解题过程中遇到的问题
/**
*@author:Lucien
*使用结构体进行多级排序
*将输入的字符串解析出名称,日期,时间,耗时,
*存入结构体,另外结构体还存一个信息,它是原来的第几个字符串
*然后将结构体进行多级排序
*/
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
struct E{
    char name[11]; //不超过10+1
    char date[11]; //4+1+2+1+2 + 1 = 11
    char time[13]; //2+1+2+1+2+1+3 + 1=13
    char cost[20]; //时间不是固定
    int pointer;
}record[10001];
/*
*@function:cmp
*@description: 比较函数,用于qsort函数
*首先比较的是消耗时间,用strtok分离出表示消耗时间的字符串
*再用atof函数将它转化成浮点数进行比较,atof函数的声明在stdlib.h中
*cmp的返回值:若希望p1排在p2的前面,返回负数,后面则返回正数
*而时间和日期的比较,可以直接使用字符串比较函数,因为它们的格式一致
*直接比较对应位上的ascii码和对应位上的数字是一样的哦
*多级排序首先判断级别高的地方是不是相等,若相等才进行下一级的判断
*cmp函数用的是结构体指针参数,我求结构体成员变量用了"."运算符,编译错误
*应该用->运算符
*/
int cmp(const void *p1, const void *p2){
    struct E * record1 = (struct E *)p1;
    struct E * record2 = (struct E *)p2;
    float cost1 = atof(strtok(record1->cost,"("));
    float cost2 = atof(strtok(record2->cost,"("));
    int result = (cost1-cost2) * 10000.0;
    /*这里返回值为整型,我之前返回的是cost1-cost2,导致返回值为0,无法正确排序*/
    if(cost1 != cost2) return result;
    if(strcmp(record1->date,record2->date)) return strcmp(record1->date,record2->date);
    return strcmp(record1->time,record2->time);
}
/*log是c库的函数,定义log数组居然冲突了,重命名为diary*/
char diary[10001][100];
int main(){
    int size,i = 0;
    //读入一行日志的时候,日志记录中需要包含空格,然鹅scanf中空格是默认的分割字符
    //所以我们在读取一行日志的时候就要用格式字符串%[]表示一个字符集
      //^表示非,那么格式字符串%[^\n]可以接收所有不是\n的字符     
      //而我们是遇到回车,行结束,当前字符串也就结束了
    //所以先接收一个包含在非'\n'的字符集的所有字符(格式字符串表示为%[^\n])
      //但是输入结束后有一个'\n'无处安放
    //方案一:scanf("%[^\n]%*c",diary[i]);其中%*c表示跳过一个字符
    //方案二:用getchar()把'\n'吸收了,scanf("%[^\n]",diary[i]);getchar();
    //不用scanf的方案gets(diary[i]);  gets函数依次读入缓冲区中的数据直到出现换行符,
    //并将除换行符外的所有已读字符保存在字符数组中,并从缓冲区去除该换行符
    //但是gets函数和scanf合用危险很大,尤其是在scanf的后面使用gets,
    //gets会读scanf剩下的'\n'
    //gets(diary[0]);
    i = 1;
    scanf("%[^\n]%*c",diary[0]);
    do{
        /*用sscanf函数解析出结构体的成员值,好处是sscanf函数不会改变原来的字符串的值
            *它和scanf的用法类似,只是输入的来源不同,一个是stdin,一个是自己给定的字符串
            */
        sscanf(diary[i-1],"%s%s%s%s", record[i-1].name, record[i-1].date, record[i-1].time, record[i-1].cost);
        record[i].pointer = i;
        scanf("%[^\n]%*c",diary[i]);
    }while(strlen(diary[i++]) != 0);
    //循环条件的退出,这里用的是字符数组,用diary[i++] != NULL不能退出循环
    //会报段错误
    /*用下面这段注释的代码代替上面的,在本地gets那块死循环,跑测试用例结果不正确,我不知道为什么,也不想管了*/
    //i = 0;
    //while(gets(diary[i])){
    //sscanf(diary[i],"%s%s%s%s", record[i].name, record[i].date, record[i].time, record[i].cost);
    //record[i].pointer = i++;
    //}
    size = i-1;//size之前写得等于i,然后就越界了。。。。
    qsort(record, size, sizeof(record[0]), cmp);
    for(i = 0; i < size; i++){
        printf("%s\n",diary[record[i].pointer]);
    }
    return 0;
}

编辑于 2019-06-25 11:13:00 回复(0)
这题看似简单,其实挺恶心的。因为我的想法是在toString中把几个字段重新拼起来,所以花了很多功夫在记录空格上。还有对日期和时间的转换,也算是把java的语法复习了一遍。
代码有点啰嗦,但至少ac了~~
import java.util.*;
import java.time.LocalDate;
import java.time.LocalTime;
public class Main {
    static class Log implements Comparable<Log> {
        private String name;
        private String date;
        private String time;
        private String duration;
        private StringBuilder space1;
        private StringBuilder space2;
        private double EPSILON = 1e-4;
        public Log(String record) {
            String[] str = record.split(" ");
            name = str[0];
            duration = str[str.length-1];
            space1 = new StringBuilder();
            space2 = new StringBuilder();
            int i = 1, j = str.length-2;
            while (str[i].isEmpty() && str[j].isEmpty()) {
                space1.append(" ");
                space2.append(" ");
                ++i;
                --j;
            }
            while (i < j && str[i].isEmpty()) {
                space1.append(" ");
                ++i;
            }
            space1.append(" ");
            date = str[i];
            while (i < j && str[j].isEmpty()) {
                space2.append(" ");
                --j;
            }
            time = str[j];
            space2.append(" ");
        }
        public String getName() {
            return name;
        }
        public String getDate() {
            return date;
        }
        public String getTime() {
            return time;
        }
        public String getDuration() {
            return duration;
        }
        public String getTimeStamp() {
            return getDate() + " " + getTime();
        }
        public String getSpace1() {
            return space1.toString();
        }
        public String getSpace2() {
            return space2.toString();
        }
        public int compareDate(Log other) {
            try {
                LocalDate ld1 = LocalDate.parse(getDate());
                LocalTime lt1 = LocalTime.parse(getTime().replace(",", "."));
                LocalDate ld2 = LocalDate.parse(other.getDate());
                LocalTime lt2 = LocalTime.parse(other.getTime().replace(",", "."));
                if (ld1.compareTo(ld2) == 0) {
                    return lt1.compareTo(lt2);
                } else {
                    return ld1.compareTo(ld2);
                }
            } catch (Exception e) {
                return getDate().compareTo(other.getDate());
            }
        }
        public int compareTo(Log other) {
            double d1 = Double.valueOf(getDuration().split("\\(")[0]);
            double d2 = Double.valueOf(other.getDuration().split("\\(")[0]);
            if (Math.abs(d1 - d2) < EPSILON) {
                return compareDate(other);
            } else if (d1 - d2 < 0) {
                return -1;
            } else {
                return 1;
            }
        }
        public String toString() {
            return getName()+getSpace1()+getTimeStamp()+getSpace2()+getDuration();
        }
        
    }
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        ArrayList<Log> logs = new ArrayList<>();
        while (reader.hasNextLine()) {
            String record = reader.nextLine();
            if(record.trim().isEmpty())
                break;
            logs.add(new Log(record));
        }
        Collections.sort(logs);
        for (Log l: logs) {
            System.out.println(l);
        }
    }
}

发表于 2018-04-02 23:04:31 回复(0)
//我也很绝望啊,啊啊啊啊啊啊啊啊啊又臭又长的代码

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef struct tesk{
    char content[100];
    char name[12];
    char st[20];
    char cu[20];
    char dur[20];
}tesk;
bool cmp(tesk a,tesk b){
    double du1,du2;
    du1=strtod(a.dur,nullptr);
    du2=strtod(b.dur,nullptr);
    int y1,y2,m1,m2,d1,d2,h1,h2,mi1,mi2,s1,s2,mm1,mm2;
    for(int i=0;i<strlen(a.st);i++){
        char temp[20];
        strncpy(temp,a.st,4);
        y1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.st+5,2);
        m1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.st+8,2);
        d1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.cu,2);
        h1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.cu+3,2);
        mi1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.cu+6,2);
        s1=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,a.cu+9,3);
        mm1=atoi(temp);
        memset(temp,0,sizeof(temp));
    }
    for(int i=0;i<strlen(b.st);i++){
        char temp[20];
        strncpy(temp,b.st,4);
        y2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.st+5,2);
        m2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.st+8,2);
        d2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.cu,2);
        h2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.cu+3,2);
        mi2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.cu+6,2);
        s2=atoi(temp);
        memset(temp,0,sizeof(temp));
        strncpy(temp,b.cu+9,3);
        mm2=atoi(temp);
        memset(temp,0,sizeof(temp));
    }
    if(du1!=du2)return du1<du2;
    if(y1!=y2)return y1<y2;
    if(m1!=m2)return m1<m2;
    if(d1!=d2)return d1<d2;
    if(h1!=h2)return h1<h2;
    if(mi1!=mi2)return mi1<mi2;
    if(s1!=s2)return s1<s2;
    else return mm1<mm2;
}
int main(){

    tesk* t=(tesk*)malloc(10000*sizeof(tesk));
    memset(t,0,10000*sizeof(tesk));
    int i1=0;
    while(gets(t[i1].content)!=NULL){
            sscanf(t[i1].content,"%s%s%s%s",&t[i1].name,&t[i1].st,&t[i1].cu,&t[i1].dur);
            i1++;
    }
    sort(t,t+i1,cmp);
    for(int i=0;i<i1;i++)printf("%s\n",t[i].content);
    return 0;
}










编辑于 2018-02-27 00:35:51 回复(1)
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while(in.hasNext()){
			try {
				
			String ts="";
			ArrayList<String> list=new ArrayList<String>();
			in.nextLine();
			while(!(ts=in.nextLine()).isEmpty()){
				list.add(ts);
			}
			
			SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
			int len=list.size();
			String text[]=new String[len];
			long date[]=new long[len];
			float time[]=new float[len];
			for (int i = 0; i < time.length; i++) {
				String tStr = list.get(i);
				String[] split = tStr.split("\\s+");
				text[i]=tStr;
				try {
					date[i]=myFormatter.parse(split[1]+" "+split[2]).getTime();
				} catch (ParseException e) {
					e.printStackTrace();
				}
				time[i]=Float.valueOf(split[3].split("\\(s\\)")[0]);
			}
//			System.out.println(Arrays.toString(text));
//			System.out.println(Arrays.toString(date));
//			System.out.println(Arrays.toString(time));
			
			float ftemp = 0;
			long ltemp=0;
			String stemp="";
			for (int i = time.length - 1; i > 0; --i)
			{
			    for (int j = 0; j < i; ++j)
			    {
			        if (time[j + 1] < time[j])
			        {
			        	ftemp = time[j];
			            time[j] = time[j + 1];
			            time[j + 1] = ftemp;
			            
			            ltemp = date[j];
			            date[j] = date[j + 1];
			            date[j + 1] = ltemp;
			            
			            stemp = text[j];
			            text[j] = text[j + 1];
			            text[j + 1] = stemp;
			        }
			        else if(time[j + 1] == time[j]){
			        	if (date[j + 1] < date[j])
				        {
				        	ftemp = time[j];
				            time[j] = time[j + 1];
				            time[j + 1] = ftemp;
				            
				            ltemp = date[j];
				            date[j] = date[j + 1];
				            date[j + 1] = ltemp;
				            
				            stemp = text[j];
				            text[j] = text[j + 1];
				            text[j + 1] = stemp;
				        }
			        }
			    }
			}
			
			for (int i = 0; i < len; i++) {
				System.out.println(text[i]);
			}
			
			} catch (Exception e) {
				System.out.println("ERROR");
			}
		}
	}
}
第一个都通不过,说我数组越界,奇怪!!!

发表于 2017-03-19 19:59:16 回复(1)
#include <cstdio>
#include <algorithm>
using namespace std;

struct Message {
    char raw[101];
    char task[21];
    int year, month, day;
    int hour, minute, second, msecond;
    int timeSecond, timeMsecond;

    bool operator < (const Message& b) const {
        if(timeSecond != b.timeSecond) return timeSecond < b.timeSecond;
        if(timeMsecond != b.timeMsecond) return timeMsecond < b.timeMsecond;
        if(year != b.year) return year < b.year;
        if(month != b.month) return month < b.month;
        if(day != b.day) return day < b.day;
        if(hour != b.hour) return hour < b.hour;
        if(minute != b.minute) return minute < b.minute;
        if(second != b.second) return second < b.second;
        return msecond < b.msecond;
    }
} message[10000];

int main() {
    int cnt = 0;
    while(gets(message[cnt].raw)) {
        sscanf(message[cnt].raw, "%s %d-%d-%d %d:%d:%d,%d %d.%d",
               message[cnt].task, &message[cnt].year, &message[cnt].month,
               &message[cnt].day, &message[cnt].hour, &message[cnt].minute,
               &message[cnt].second, &message[cnt].msecond, &message[cnt].timeSecond, &message[cnt].timeMsecond);
        cnt++;
    }
    sort(message, message+cnt);
    for(int i = 0; i < cnt; i++) {
        printf("%s\n", message[i].raw);
    }
    return 0;
}

编辑于 2018-02-06 15:16:32 回复(4)

做完这道题,人感觉老了一岁

package com.speical.first;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

/** 
* 多key排序问题
* @author special
* @date 2017年12月24日 下午5:14:26
*/
public class Pro30 {
    private static final double min = 1e-7;

    static class StringComparator implements Comparator<String>{

        @Override
        public int compare(String o1, String o2) {
            /**
             * 注意这里的正则表达式写
             * 不能用o1.split(" "),这样只是按照一个空格进行划分
             * 会导致a    b 形成的数组为{a,,,,,b} so,你懂得
             */
            String[] str1 = o1.split("\\s+");
            String[] str2 = o2.split("\\s+");
            /**
             * 比较时间,因为时间的长度不一致,所以不能直接字符串比较,否则就会按字典序排序
             * 比如101.11会排在11.11的前面,显然这样是不对的
             * 这里也很好的说明了为什么对于不定长的字符串进行基数排序会出现错误的情况
             * 所以这里我们化为double型比较
             */
            double time1 = Double.parseDouble(str1[3].substring(0,str1[3].length() - 3));
            double time2 = Double.parseDouble(str2[3].substring(0,str2[3].length() - 3));

            if(Math.abs(time1 - time2) > min){ //比较时间
                if(time1 - time2 > 0) return 1;
                else                  return -1;
            }else if(!str1[1].equals(str2[1])){ //比较年月日,因为定长可直接比较
                return str1[1].compareTo(str2[1]);
            }else if(!str1[2].equals(str2[2])){ //比较时间,因为定长可直接比较
                return str1[2].compareTo(str2[2]);
            }else{
                return 0;  
            }
        }

    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner input = new Scanner(System.in);
        List<String> strs = new ArrayList<>();
        /**
         * 坑爹的最后空一行,用hasNextLine()即可
         */
        while(input.hasNextLine()){
            String str = input.nextLine();
            if(str.trim().isEmpty()) break;
            strs.add(str);
        }
        Collections.sort(strs, new StringComparator());
        for(String item : strs){
            System.out.println(item);
        }
    }

}
发表于 2017-12-24 19:37:46 回复(3)
这题真实让人头秃,主要是这么几个问题:
1、输入的问题:
    istringstream 这个之前确实没有用过,但稍微查了一下之后也就ok了,不是大问题(C语言里是sscanf,用法差不多);
2、比较的问题:
    刚开始我的日期day和时分秒hms都是用char数组保存的,然后在比较函数Cmp中直接返回strcmp() < 0。提交之后一直显示答案错误,但预期输出和实际输出对比又是完全相同的,自己测试了一些数据之后也是完全符合题目要求的。然后我又去不停地看其他人的代码,后来发现字符串可以直接进行比较,修改之后再提交就通过了。为什么会这样,我也不知道,如果有大佬知道麻烦告知。
最后的代码还是挺简单的:
#include <iostream>
#include<string>
#include <algorithm>
#include<sstream>
using namespace std;

struct Log
{
    string line;//记录整行数据,便于输出
    string name, day, hms;
    float time;
};

bool Cmp(Log& l1, Log& l2)
{
    if (l1.time == l2.time)
    {
        if (l1.day == l2.day)
            return l1.hms < l2.hms;
        else
            return l1.day < l2.day;
    }
    else
        return l1.time < l2.time;
}

int main()
{
    Log logs[10001];
    int i = 0;
    while (getline(cin, logs[i].line))
    {
        if (logs[i].line.length() == 0)
            break;
        istringstream l(logs[i].line);
        l >> logs[i].name >> logs[i].day >> logs[i].hms >> logs[i].time;//类似于C中的sscanf
        i++;
    }
    sort(logs, logs + i, Cmp);
    for (int j = 0; j < i; j++)
        cout << logs[j].line << endl;
    return 0;
}


发表于 2021-02-23 11:37:41 回复(0)

看了下python通过的解法,有点麻烦,对于其他语言的解法,更繁琐。

所以我分享一下我简单的解法,只需要十行。


res=[]
str = input()
while str:
    res.append(str)
    try:
        str = input()
    except:
        break
res.sort(key=lambda c: (float(c.split()[-1].rstrip("(s)")), c.split()[1], c.split()[2]))
for i in res:    print(i)

其中处理输入就用了八行,第九行是排序,第十行是输出结果。

这是python3下,测试通过,如果是python2,只需要将input()改为raw_input()也能通过。


解释一下代码,前8行是将日志放到一个res数组中,每个元素都是一行。

第9行是多key排序,第一按照运行时间,如果运行时间相同,按任务开始时间。

编辑于 2017-10-16 16:22:57 回复(0)
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <sstream>
using namespace std;

vector<string> split0(string &s, const char pattern) {
	vector<string> res;
	stringstream input(s);
	string temp;
	while (getline(input, temp, pattern)) {
		if (temp != "") {
			res.push_back(temp);
		}
	}
	//for (int i = 0; i < res.size(); i++) {
	//	cout << res[i] << endl;
	//}
	return res;
}

bool cmp(string a, string b) {
	vector<string> str_a;
	vector<string> str_b;
	str_a = split0(a, ' ');
	str_b = split0(b, ' ');
	//for (int i = 0; i < str_a.size(); i++) {
	//	cout << str_a[i] << endl;
	//}
	double duration1 = atof(str_a[3].substr(0, str_a[3].length() - 3).c_str());
	double duration2 = atof(str_b[3].substr(0, str_b[3].length() - 3).c_str());
	if (duration1 != duration2) {
		return duration1 < duration2;
	}
	else
	{
		return strcmp((str_a[1] + str_a[2]).c_str(), (str_b[1] + str_b[2]).c_str()) < 0;
	}
}

int main()
{
	int i = 0;
	string arr[10001];
	while (getline(cin, arr[i]) && arr[i].length() != 0) {
		i++;
	}
	sort(arr, arr + i, cmp);
	for (int j = 0; j < i; j++) {
		cout << arr[j] << endl;
	}
	return 0;
}

 此题为一道排序题,包含以下知识点
  1. 整体思路为:algorithm中的sort方法进行排序,并重载cmp函数,比较时要分情况,考虑时长相等时的比较规则
  2. 输入带空格字符串处理:当输入字符串为一行且带有空格时,不能用cin或scanf,考虑getline,可以接受空格
  3. 字符串分割:使用sstream进行字符串分割,使用到getline(input, temp, pattern)
  4. 字符串类型转换:这也是第一次做漏掉的一个问题,时长的比较不能直接用strcmp,因为要考虑长度不同的情况!!应该先转换成double类型(atof函数+c_str函数)
  5. 结束条件判断:当接受的字符串数组长度为0时结束输入。
发表于 2019-08-16 15:21:04 回复(0)

人生苦短~

import sys
datas = sys.stdin.readlines()
datas.sort(key=lambda x: (float(x.split()[-1][:-3]), x.split()[1:3]))
for i in datas:
    print(i[:-1])            #去除行尾回车键
编辑于 2018-10-09 10:19:30 回复(0)
/*
又是字符串模拟,以及多键值对排序
因为考虑到格式问题我直接使用了string以及getline读入,getline默认读到‘\n’结束了.
因为涉及到时间排序,该开始天真的直接用字符串排序了,发现没过样例。。。
这里利用string的substr函数分解出对应的部分,然后将时间的整数与小数部分分离
然后进行排序即可.
substr(start,len),表示从start开始去长度为len的子串.

*/


#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e4+5;

struct node
{
    string s;
    string name,date;
    int time1,time2;
    node(string ss = "",string nname = "",string ddate = "",int ttime1 = 0,int ttime2 = 0)
    {
        s = ss;
        name = nname,date = ddate,time1 = ttime1,time2 = ttime2;
    }
}a[maxn];

bool cmp(node x,node y)
{
    if(x.time1 != y.time1)
        return x.time1 < y.time1;
    else if(x.time2 != y.time2)
        return x.time2 < y.time2;
    else
        return x.date < y.date;
}
int main()
{
    int cnt = 0;
    string s,name,date,time;
    while(getline(cin,s))
    {
        int flag = 1,pre = -1;
         for(int i = 0;i < s.size();++i)
         {
             if(s[i] == ' ')
             {
                 if(flag == 1)
                 {
                    name = s.substr(0,i);
                    flag = 0;
                    //cout << i << endl;
                 }
                 if(flag == 2 && pre != -1)
                    {
                        date = s.substr(pre,i - pre ),flag = 3,pre = -1;
                        //puts("***");
                    }
             }
             else if(s[i - 1] == ' ' && pre == -1 && s[i] != ' ')
             {
                 pre = i;
             }
             else if(s[i] == ',')
                flag = 2;
             else if(s[i] == ')' && flag == 3)
             {
                 time = s.substr(pre,i);
             }
         }
         int x1 = 0,x2 = 0;
         flag = 0;
         for(int i = 0;i < time.size();++i)
         {
             if(time[i] == '.')
            {
                flag = 1;
                continue;
            }
             if(flag == 0)
                x1 = x1 * 10 + time[i];
             else
                x2 = x2 * 10 + time[i];
         }
         //cout << name << endl;
         //cout << date << endl;
         a[cnt++] = node(s,name,date,x1,x2);
    }
         sort(a,a + cnt,cmp);
        for(int i = 0;i < cnt;++i)
        {
            cout << a[i].s << endl;
        }
    return 0;
}

编辑于 2018-04-30 15:56:36 回复(0)