Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 一段时间内的随机事件数_C_Algorithm - Fatal编程技术网

C 一段时间内的随机事件数

C 一段时间内的随机事件数,c,algorithm,C,Algorithm,我需要跟踪给定时间段内随机事件的数量。我可以检测到事件的最大速率是每秒一次,我需要能够提供过去30分钟内的事件数 我在这个算法上的第一个漏洞是有一个数组,它能以秒为单位保存时间戳。每次发生新事件时,所有时间戳都会下移,新事件将放置在数组的前面。当请求事件数时,我删除所有大于30分钟的事件,然后返回结果计数 time_t event_stamps[60 * 30]; unsigned event_count; void events_put() { time_t new_event_ti

我需要跟踪给定时间段内随机事件的数量。我可以检测到事件的最大速率是每秒一次,我需要能够提供过去30分钟内的事件数

我在这个算法上的第一个漏洞是有一个数组,它能以秒为单位保存时间戳。每次发生新事件时,所有时间戳都会下移,新事件将放置在数组的前面。当请求事件数时,我删除所有大于30分钟的事件,然后返回结果计数

time_t event_stamps[60 * 30];
unsigned event_count;

void events_put()
{
    time_t new_event_time = SomeCallToGetTheCurrentTimeInSeconds();

    /* Shift values down the array to make space for the new value at index 0 */
    int i;
    for(i = sizeof(event_stamps) / sizeof(event_stamps[0]); --i > 0; )
    {
        event_stamps[i] = event_stamps[i-1];
    }

    event_stamps[0] = new_event_time;

    if(event_count < sizeof(event_stamps) / sizeof(event_stamps[0]))
    {
        event_count++;
    }   
}

uint32_t events_get(void)
{
    time_t systime_s = SomeCallToGetTheCurrentTimeInSeconds();

    /* Remove elements in the array that are occurred greater than 30 minutes ago */
    int i;
    for(i = event_count; --i >= 0; )
    {
        /* Events arrive in order so events further away in time occur at higher array
         * indices. Therefore, once an event is reached that is sooner than the cutoff
         * time (30 minutes * 60 seconds), there are no more events to remove */
        if(systime_s - event_stamps[i] <= (30 * 60))
        {
            break;
        }

        event_count--;
    }

    return event_count;
}
时间事件戳[60*30];
未签名事件计数;
作废事件
{
time\u t new\u event\u time=SomeCallToGetTheCurrentTimeInSeconds();
/*向下移动数组中的值,为索引0处的新值留出空间*/
int i;
对于(i=sizeof(event_stamps)/sizeof(event_stamps[0]);i>0;)
{
活动邮票[i]=活动邮票[i-1];
}
事件标记[0]=新事件时间;
if(事件计数=0;)
{
/*事件按顺序到达,因此时间越远的事件发生在更高的数组中
*指数。因此,一旦达到某个事件,该事件比截止时间早
*时间(30分钟*60秒),没有其他要删除的事件*/

如果(系统时间-事件时间戳[i]使用按秒索引的循环位数组:1800位持续30秒

记录上次活动的时间

设置适当的位并记录事件发生的时间,但首先清除上一个事件时间和现在之间的所有位


报告事件数时,首先清除上一个事件时间和现在之间的所有位,然后计数位。

如果您只需要保存过去30分钟(1800秒)的历史记录,并且每秒只能有一个事件,那么每个事件只需要一个位,因此请使用位字段。每个位的索引表示与当前时间的偏移量(以秒为单位)

每秒循环重复一次:
整个字段向右移动一位。最后一位(代表1800秒前的事件)将从数组中删除。如果是一位,则减小事件计数器。检查事件是否在这一秒发生,如果是,则索引0处的位设置为一,并增加事件计数器。(可以使用表示时间偏移0的附加索引变量,而不是移动整个数组。)


如果事件或非事件很少,则可以使用来实现额外的内存改进。

使用环形缓冲区是否比不断移动数组内容更有效?是否只需要跟踪1800秒范围内的事件数?@2501是的,仅跟踪最后1800秒内的事件数。