【问题标题】:how to track max/min values for the last minute?如何跟踪最后一分钟的最大值/最小值?
【发布时间】:2012-08-30 07:33:55
【问题描述】:

我想创建这样的类:

public TrackMaxMin(int periodInSec)

// use current system time as time
public Add(decimal value)

// return maximum Value for the last periodInSec
public Max { get {} }

// return minimum Value for the last periodInSec
public Min { get {} }

我想我可以使用 FIFO 查询来存储 Pair<DateTime, decimal> 并且在每个 Add 调用中我应该:

  • 从查询中删除“过时”的值。如果需要,删除“更新”缓存的 Max/Min 时
  • 添加新值。如果需要,更新 Max/Min

我的解决方案简单明了。或许您可以提出更好的建议?

【问题讨论】:

  • 你可以使用Queue class作为基础存储来构建你的类
  • “简单明了” 是好的方法的特征。

标签: c# algorithm


【解决方案1】:

您可以使用称为maxmax-heap、称为minmin-heap 和称为qqueue

x 成为具有x.timex.val 属性的元素。

Add 被调用时:

  • Create 一个新元素 x
  • Add x 到所有数据结构。

Add的运行时间为O(lgn)

Max 被调用时:

  • max.GetMax()

Max的运行时间为O(1)

Min 被调用时:

  • min.GetMin()

Min的运行时间为O(1)

为了模型的维护,这样做:

只有一个计时器,每次在q 中的下一个外出元素的周期到期时触发。

x的期限到期时:

  • q.Dequeue(), max.Delete(x), min.Delete(x)

【讨论】:

  • 唯一的问题是我必须不断添加O(log n)。我目前使用简单的方法。添加是 O(1)。 Min/Max 在大多数情况下为 O(1),在最坏情况下为 O(n),平均为 O(logn)。
  • O(lgn) 在大多数情况下就像 O(1),那么再次使用 3 个数据结构可能会超出您的要求。
【解决方案2】:

您可以将每对存储在一个队列中。您应该将数据保留至少一分钟,然后在调用 Add 时删除陈旧的数据。

但是,您应该通过循环遍历堆栈数据来动态计算 Max 和 Min,否则您将失去数据完整性。

【讨论】:

  • 我真的认为应该在这里使用queue,而不是stack,因为我需要清理最旧的值。此外,只有在值更新时才需要重新计算 Max/Min。在大多数情况下,Max/Min 不会改变。
  • 你说你想跟踪最后一分钟的最小值和最大值,所以如果你在 90 秒前的最大值为 100,在 45 秒前的最大值为 50,那么 Max() 应该返回50,对吧?这将需要一个计算字段。
【解决方案3】:

这很方便,

System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Start();
s.Stop();
long elapsedms = s.ElapsedMilliseconds;

【讨论】:

  • 所以您建议为每个项目存储Stopwatch?但是计算DateTime和当前时间之间的差异也很容易......
  • 为什么秒表会有帮助?
  • 是的,很容易计算经过的时间,这是客观的。如果您认为替代方式很方便,那么值得使用它而不是我们自己的编码.. :)
猜你喜欢
  • 2012-07-19
  • 2021-06-01
  • 2015-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2020-02-10
相关资源
最近更新 更多