hihocodert #1057 : Performance Log

题目来源:hihocoder练习题网站

题目如下:
时间限制:8000ms
单点时限:1000ms
内存限制:256MB

描述
You are given a txt file, which is performance logs of a single-threaded program.
Each line has three columns as follow:
[Function Name] [TimeStamp] [Action]
[FunctionName] is a string of length between 1~255
[TimeStamp] format is hh:mm:ss
Valid values for “Action” column are START or END, marking the start or end of a function call.
Each function will only be called once.
Output the depth-first traversal result of the call graph with the total time of each function call. However, sometimes the performance log isn’t correct and at that time you just need to output “Incorrect performance log”.
输入
The input only contains 1 case, first line is a positive number N representing the number of logs(1 <= N <= 20000), then there are N lines in next, each line is the log info containing [Function Name] [TimeStamp] [Action], [Function Name] is a string, you can assume the [Function Name] is distinct and the length between 1~255.
输出
Output the depth-first traversal result of the call graph with the total time of each function call for the correct performance, or output “Incorrect performance log”.
提示
A call graph is a directed graph that represents calling relationships between subroutines in a computer program.
Call graph for the sample input is shown as below:
测试案例所生成的调用树
样例输入
8
FuncA | 00:00:01 | START

FuncB00:00:02START
FuncC00:00:03START
FuncC00:00:04END
FuncB00:00:05END
FuncD00:00:06START
FuncD00:00:07END
FuncA00:00:08END

样例输出

FuncA00:00:07
FuncB00:00:03
FuncC00:00:01
FuncD00:00:01

解析:
看到题目的时候吓了一跳,英文,通过人数少,以为是非常难的一道题,看过题目之后发现是输出“调用树”的深度优先探索过程,同时还提醒日志有可能是错误的。
当我一看到深度优先探索的时候,下意识的就想到栈:stack!
所以这道题目是很简单的,解题思路如下:
1.挨个取入日志文件,遇到”START“就将日志数据入栈;
2.遇到”END“则意味着要出栈,此时查看是否与栈顶日志数据名称是否一致,若一致,此时再查看时间是否正确,若符合时间先后顺序要求,则计算好运行时间,并出栈;若否,则终止程序,输出错误提示;
3.按照入栈出栈的顺序,若日志文件正确,最终的栈空间应该为0;但题目中提示过日志文件有可能是假的,所以程序运行完之后,输出结果前应再次判断栈是否为空,不为空,则输出日志错误提示。(本人也是因为这个原因一直无法通过测试)

**#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
using std::cout;
using std::cin;
using std::endl;
using std::stack;
using std::vector;
using std::string;
using std::to_string;
struct Node
{
    char name[256];  // 调用函数名
    char time[10];   // 时间戳
    char action[6];  // 函数执行动作
};
void getTime(char* end, char* start,string& time)
{
    int eh, em, es, sh, sm, ss;
    int th, tm, ts;
    eh = (end[0] - '0') * 10 + end[1] - '0';
    em = (end[3] - '0') * 10 + end[4] - '0';
    es = (end[6] - '0') * 10 + end[7] - '0';
    sh = (start[0] - '0') * 10 + start[1] - '0';
    sm = (start[3] - '0') * 10 + start[4] - '0';
    ss = (start[6] - '0') * 10 + start[7] - '0';
    // 计算秒
    if (es < ss)
    {
        em--;
        ts = es + 60 - ss;
    }
    else
    {
        ts = es - ss;
    }
    // 计算分
    if (em < sm)
    {
        eh--;
        tm = em + 60 - sm;
    }
    else
    {
        tm = em - sm;
    }
    // 计算时
    if (eh < sh)
    {
        th = eh + 24 - sh;
    }
    else
    {
        th = eh - sh;
    }
    time[0] = time[3] = time[6] = '0';
    time[2] = time[5] = ':';
    time[0] = th / 10 + '0';
    time[1] = th % 10 + '0';
    time[3] = tm / 10 + '0';
    time[4] = tm % 10 + '0';
    time[6] = ts / 10 + '0';
    time[7] = ts % 10 + '0';
}
int main(void)
{
    int N, size_res;
    bool flag = false;
    char tname[256], ttime[10], taction[6]; 
    stack<struct Node> callstack;
    static string res[20020];
    cin >> N;
    size_res = 0;
    while (N--)
    {
        memset(tname, 0, sizeof(tname));
        memset(ttime, 0, sizeof(ttime));
        memset(taction, 0, sizeof(taction));
        cin >> tname >> ttime >> taction;
        if (!strcmp(taction, "START")) // 遇到“START”关键字,表示调用函数操作,则进行入栈操作
        {
            struct Node tmp;
            strcpy(tmp.name, tname);
            strcpy(tmp.time, ttime);
            strcpy(tmp.action, taction);
            callstack.push(tmp); // 元素入栈
            res[size_res++] = string(tname);
        }
        else if (!callstack.empty() && !strcmp(callstack.top().name, tname)// 遇到“end”关键字,表示要进行终止函数调用操作,也即出栈操作
            && (strcmp(callstack.top().time, ttime) <= 0)) 
        {
            //1.计算时间
            string ti = "        ";
            getTime(ttime, callstack.top().time, ti); // 计算程序消耗时间
            int i;
            for (i = 0; res[i] != tname && i < size_res; i++);
            //2.储存结果
            res[i] = res[i] + " " + ti;
            //3.元素出栈
            callstack.pop();
        }
        else // 栈已空,但是仍需出栈操作,说明日志不正确
        {
            flag = true;
        }   
    }
    if (true == flag || !callstack.empty()) // 因为题目提示过,日志有可能是错误的,所以最后再判断一下栈是否为空
    {
        cout << "Incorrect performance log" << endl;
    }
    else
    {
        for (int i = 0; i < size_res; i++)
        {
            cout << res[i] << endl;
        }
    }

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值