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

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

思路:先将时间区间点排序,然后遍历计数,遇到启动+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  0x7fffffff

typedef 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值