下午好!
我正在尝试制作某种圆形堆叠。它应该像普通的LIFO堆栈,但没有明显的限制。而不是达到最大容量,它应该消除或跳过那时候适时引入的第一个元素!
例如:
假设我们有一个包含3个元素的堆栈:stack[3]
我们通过“推” 3个内部元素来填充它:push[a], push[b], push[c]
。
但是随后我们将要添加第4个和第5个元素:push[d], push[e]
。
标准堆栈会说堆栈达到了极限,无法再添加任何元素。
但是我想要一个循环堆栈,该循环堆栈将消除或跳过a
和b
,请记住c
,d
和e
并输出{{1 }},e
和d
;
该项目在ESP32上的PlatformIO中完成,因此我无权访问C ++ STL,即使我拥有,我也认为仅用1个堆栈编译这么大的库是没有意义的。
即使有段时间我认为我应该编译一个类似的库,使我可以使用c
或stack
,那段时间也已荡然无存,因为现在我感觉自己像个白痴,可以找出数学问题。这已经困扰了我一个多星期了。
我只能在网上找到以下FIFO循环缓冲区:
deque
过去三天我一直在修补它,但是我无法使其按我想要的方式工作。
作为FIFO结构,它将打印class circular_buffer {
public:
explicit circular_buffer(size_t size) :
buf_(std::unique_ptr<T[]>(new T[size])),
max_size_(size)
{
}
void put(T item)
{
std::lock_guard<std::mutex> lock(mutex_);
buf_[head_] = item;
if(full_) {
tail_ = (tail_ + 1) % max_size_;
}
head_ = (head_ + 1) % max_size_;
full_ = head_ == tail_;
}
T get()
{
std::lock_guard<std::mutex> lock(mutex_);
if(empty())
{
return T();
}
//Read data and advance the tail (we now have a free space)
auto val = buf_[tail_];
full_ = false;
tail_ = (tail_ + 1) % max_size_;
return val;
}
void reset()
{
std::lock_guard<std::mutex> lock(mutex_);
head_ = tail_;
full_ = false;
}
bool empty() const
{
//if head and tail are equal, we are empty
return (!full_ && (head_ == tail_));
}
bool full() const
{
//If tail is ahead the head by 1, we are full
return full_;
}
size_t capacity() const
{
return max_size_;
}
size_t size() const
{
size_t size = max_size_;
if(!full_)
{
if(head_ >= tail_)
{
size = head_ - tail_;
}
else
{
size = max_size_ + head_ - tail_;
}
}
return size;
}
private:
std::mutex mutex_;
std::unique_ptr<T[]> buf_;
size_t head_ = 0;
size_t tail_ = 0;
const size_t max_size_;
bool full_ = 0;
};
,a
,b
或c
,c
,d
。
在这种情况下,我希望它从上到下,从头到尾打印,但是我无法弄清楚。
答案 0 :(得分:4)
如果我的理解正确,那么您所寻找的只是一个固定大小的缓冲区,该缓冲区具有指向“堆栈”“顶部”的单个指针,该指针递增/递减,以便环绕结尾缓冲区的。这将自动导致最新的条目始终覆盖最旧的条目,从而有效地为您提供了最后N个值的LIFO存储,其中N是缓冲区大小。例如:
/home
请注意,这种简单的实现不是线程安全的……