给出进程启动区间计算任意时间点并行进程数量

来源:互联网 发布:韩国社交软件排名 编辑:程序博客网 时间:2024/06/05 21:09

题目:原题不公开,需求是给出大量进程的启动和结束时间,计算任意时间点进程并发数。进程数有限,查询次数很大。关闭开区间: [启动,关闭)

思路:先将时间区间点排序,然后遍历计数,遇到启动+1,遇到关闭-1,时间点切换时,就得出上个值到当前值区间的进程数

接口定义如下:

void number_of_tasks_running(        OUT int result[],  //输出结果        IN int start[],    //启动时间点        IN int end[],      //结束时间点        IN int n,          //进程数        IN int query[],    //查询种子        IN int m)          //查询数量
原版本代码所有算法都是自行实现的,效率要好一些但是篇幅偏长,下文的代码用stl简化了一下


#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <vector>#include <map>#include <algorithm>using namespace std;#define IN#define OUT#define INT_MIN  0#define INT_MAX  0x7ffffffftypedef enum{        S_START,        S_END,} status_t;class Node{public:        status_t m_type;        int m_value;        Node(){}        Node(int value, status_t type):m_type(type), m_value(value){}        bool operator<(const Node& n2) const        {                return m_value < n2.m_value || (m_value == n2.m_value && m_type == S_START);    //升序排列,开始在前        }};class Range{public:        uint32_t m_beg;        uint32_t m_end;        Range(uint32_t beg, uint32_t end) : m_beg(beg), m_end(end) {}        bool operator<(const Range& n2) const        {                if(n2.m_beg >= m_beg && n2.m_end < m_end)                        return false;                return m_beg < n2.m_beg;        }};/* * 功能:合并区间,计数 */void CountRange(vector<Node>& points, map<Range, int>& rst){        if(points.size() < 2)                return;        //计算合并区间数        int cnt = 0;        int last = INT_MIN;        int beg = last;        for(vector<Node>::iterator itr = points.begin(); itr != points.end(); itr++)        {                if(itr->m_value != last)                {                        rst[Range(beg, itr->m_value)] = cnt;                        last = itr->m_value;                        beg = last;                }                if(itr->m_type == S_START)                        cnt++;                else                        cnt--;        }        rst[Range(beg, INT_MAX)] = 0;   //后开区间}/* * 功能:计算并行任务数量 */void number_of_tasks_running(        OUT int result[],        IN int start[],        IN int end[],        IN int n,        IN int query[],        IN int m){        //点序列        vector<Node> points;        points.resize(2*n);        for(int i = 0; i < n; i++)        {                points[i] = Node(start[i], S_START);                points[i+n] = Node(end[i], S_END);        }        //排序,计算最小一致区间        sort(points.begin(), points.end());        map<Range, int> rst;        CountRange(points, rst);        //        for(map<Range, int>::iterator itr = rst.begin(); itr != rst.end(); itr++)                printf("%d - %d %d\n", itr->first.m_beg, itr->first.m_end, itr->second);        //        for(int i = 0; i < m; i++)        {                map<Range, int>::iterator itr = rst.find(Range(query[i], query[i]+1));                result[i] = itr->second;        }}//以下是测试代码/* * 功能:打印数组 */void dump_array(int arr[], int size, const char* info){        int i;        printf("%s\t:[", info);        for(i = 0; i < size; i++)                printf("%2d, ", arr[i]);        printf("]\n");}int main(int agc, char* argv[]){        int start[] = {0, 2, 5};        int end[] = {4, 7, 8};        int n = sizeof(start)/sizeof(int);        int query[] = {1, 9, 4, 3, -1, 0, 2, 4, 5, 7, 8};        int m = sizeof(query)/sizeof(int);        int* rst = new int[m];        number_of_tasks_running(rst, start, end , n, query, m);        dump_array(start, n, "start");        dump_array(end, n, "end");        dump_array(query, m, "query");        dump_array(rst, m, "out");        delete rst;        return 0;}