我真的不知道如何总结标题中的问题,对不起。 :)
假设我有一个包含数千个对象的集合(即ObservableCollection)。这些对象由升序时间戳和FALSE
布尔值(非常简化)组成。
像这样:
[0] 0.01, FALSE
[1] 0.02, FALSE
[2] 0.03, FALSE
[3] 0.04, FALSE
...
现在,让我们假设在这个集合中,有些块的标志设置为TRUE
。
像这样:
[2345] 23.46, FALSE
[2346] 23.47, FALSE
[2347] 23.48, FALSE
[2348] 23.49, TRUE
[2349] 23.50, TRUE
[2350] 23.51, TRUE
[2351] 23.52, TRUE
[2352] 23.53, TRUE
[2353] 23.54, FALSE
[2354] 23.55, FALSE
...
我需要找到块并在块之前和之后的1.5秒内将所有标志设置为TRUE
。
如何在保持合理性能的同时实现这一目标?
答案 0 :(得分:2)
马蒂亚斯G解决方案是正确的,虽然很慢 - 似乎有n平方的复杂性。
首先扫描输入values
以通过IsActive过滤它们,检索时间戳并放入新列表 - 至少是O(n)。然后它扫描构造的列表,在最坏的情况下可能是整个输入 - O(n),并且对于检索到的每个时间戳,它扫描输入values
以修改它们的适当值 - O(n ^ 2)。
然后它构建额外的列表只是为了扫描一次并销毁。
我建议一个类似于mergesort的解决方案。首先扫描输入值,并为每个活动项目将适当的时间间隔推入队列。您可以延迟推送以查看下一个间隔是否与当前间隔重叠 - 然后延长间隔而不是推动。输入列表完成后,最后按下最后一个延迟间隔。这样,您的队列将包含您想要修改的(几乎)最少数量的时间间隔。
然后再次扫描values
数据并将时间戳与队列中的第一个间隔进行比较。如果项目的时间戳落入当前间隔,请将项目标记为“活动”。如果它超过了间隔,则从队列中删除间隔并将时间戳与下一个时间戳进行比较 - 依此类推,直到该项位于间隔中或之前。您的输入数据按时间顺序排列,因此间隔也将按相同的顺序排列。这允许通过两个列表在单个并行传递中完成任务。
答案 1 :(得分:1)
假设您有这样的数据结构:
修改:将TimeStamp更改为double
public class Value
{
public double TimeStamp { get; set; }
public bool IsActive { get; set; }
}
此对象的列表名为values
。然后,您可以搜索活动数据集,并为每个数据集将它们周围的值标记为活动数据:
double range = 1.5;
var activeTimeStamps = values.Where(value => value.IsActive)
.Select(value => value.TimeStamp)
.ToList();
foreach (var timeStamp in activeTimeStamps)
{
var valuesToMakeActive =
values.Where
(
value =>
value.TimeStamp >= timeStamp - range &&
value.TimeStamp <= timeStamp + range
);
foreach (var value in valuesToMakeActive)
{
value.IsActive = true;
}
}
无论如何,我想会有一个性能更好的解决方案..