有没有办法做圆形堆叠?

时间:2019-03-22 15:50:15

标签: c++ stack circular-buffer lifo

下午好!

我正在尝试制作某种圆形堆叠。它应该像普通的LIFO堆栈,但没有明显的限制。而不是达到最大容量,它应该消除或跳过那时候适时引入的第一个元素!

例如:

假设我们有一个包含3个元素的堆栈:stack[3]

我们通过“推” 3个内部元素来填充它:push[a], push[b], push[c]

但是随后我们将要添加第4个和第5个元素:push[d], push[e]

标准堆栈会说堆栈达到了极限,无法再添加任何元素。

但是我想要一个循环堆栈,该循环堆栈将消除或跳过ab,请记住cde并输出{{1 }},ed

该项目在ESP32上的PlatformIO中完成,因此我无权访问C ++ STL,即使我拥有,我也认为仅用1个堆栈编译这么大的库是没有意义的。 即使有段时间我认为我应该编译一个类似的库,使我可以使用cstack,那段时间也已荡然无存,因为现在我感觉自己像个白痴,可以找出数学问题。这已经困扰了我一个多星期了。

我只能在网上找到以下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; }; abccd

在这种情况下,我希望它从上到下,从头到尾打印,但是我无法弄清楚。

1 个答案:

答案 0 :(得分:4)

如果我的理解正确,那么您所寻找的只是一个固定大小的缓冲区,该缓冲区具有指向“堆栈”“顶部”的单个指针,该指针递增/递减,以便环绕结尾缓冲区的。这将自动导致最新的条目始终覆盖最旧的条目,从而有效地为您提供了最后N个值的LIFO存储,其中N是缓冲区大小。例如:

/home

请注意,这种简单的实现不是线程安全的……