假设您在.NET中有一个Queue实例(Systems.Generic.Collections.Queue)。该队列有10个元素,其中元素9(从0开始计数)是队列中最近添加的元素。
所以队列看起来像这样:
{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}
其中0.1是Dequeue上要弹出的下一个元素,1.0是最近添加的项目。
我想删除最近添加的5个项目 队列最终看起来像这样(我需要在队列中保持相同数量的元素,因此大小不会减少):
{0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5}
在.NET中实现这一目标的最快方法是什么
澄清:
t = 0:队列已初始化
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}
t = 1:添加一个元素
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1}
t = 2:添加了一个元素
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2}
t = 3:添加了一个元素
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3}
t = 4:最近添加的两个元素是"删除" (及时倒退)
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1}
背景资料:
我将样品推到缓冲液中。缓冲区基本上是长流样本上的滑动窗口。有时我想"倒带"窗户;那就是:及时移回它,因为我推的样品应该被丢弃。我不知道是否应该提前丢弃样品。我必须推动样品,对"窗口中的样品进行一些计算。然后决定窗口是否应该"备份"及时。
更新
要求:
实现具有N个固定大小的缓冲区X.缓冲区中最旧的元素位于索引0(X [0])。缓冲区中的最新元素是索引N-1(X [N-1])
实施方法'写'它将一个样本s写入缓冲区。当样本写入缓冲区时,缓冲区中的样本将被移位 对于j = 0到j = N-2且X [N-1] = s,X [j] = X [j + 1]。
在任何给定时间,都应提供以下方法:
"倒带":实现一个方法,复制从索引0到索引K-1的K个元素,并将它们放在缓冲区的末尾。因此,最初在索引K-1处的样本将移动到索引N-1,并且最初在索引0处的样本移动到索引(N-1) - (K-1)。索引0到索引K-1的样本随后设置为0.
我希望上面说明我想要的东西。感谢。
答案 0 :(得分:1)
所以,根据你的新要求,我会实现这个类:
public class Buffer
{
public Buffer(int N) { }
public void Write(double value) { }
public double Maximum { get { return 0.0; } }
public double Minimum { get { return 0.0; } }
public double Average { get { return 0.0; } }
public double this[int n] { get { return 0.0; } }
public void Rewind(int k) { }
}
这段代码显然只是shell - 我已经将内部工作留给你进行编码了。
我精确地遵循了你的要求结构。
目前编写的代码应该有助于使其成为一个很好的起点。
我建议您首先使用数组作为基础数据结构(即double[N]
)来实现。如果您实现此代码并且它足够有效,那么您就完成了。如果没有,那么尝试使用LinkedList<double>
- 这将更难编码,但它应该更快,虽然没有运行你的代码,我无法告诉你。
答案 1 :(得分:1)
虽然您对Rewind
操作的预期行为仍然有些不清楚,但您似乎需要类似固定大小ring buffer的内容。因此,如果我误解了应该如何工作,请在您的问题中进一步澄清。
public class RewindableRingBuffer<T>
{
private readonly T[] _values;
private int _head; // index of oldest value
private int _count; // number of elements
public RewindableRingBuffer(int capacity)
{
_values = new T[capacity];
_head = 0;
_count = 0;
}
public int Count { get { return _count; } }
public T this[int index]
{
get
{
if ((uint)index >= (uint)_count)
throw new IndexOutOfRangeException("index");
return _values[(_head + index) % _values.Length];
}
}
public void Add(T value)
{
var tail = (_head + _count) % _values.Length;
if (_count < _values.Length)
_count++; // was not yet filled to capacity.
else
_head = (_head + 1) % _values.Length; // remove oldest.
_values[tail] = value;
}
public T Min
{
get { return Enumerate().Min(); }
}
public T Max
{
get { return Enumerate().Max(); }
}
public IEnumerable<T> Enumerate()
{
// enumerates oldest to newest.
for (var i = 0; i < _count; i++)
yield return _values[(_head + i) % _values.Length];
}
public void RewindBy(int num)
{
// Goes back in history, by removing the 'num'
// most recent values.
_count = Math.Max(0, _count - num);
}
}
答案 2 :(得分:0)
我最终在这些阵列上使用常规数组和复制方法来实现所需的功能