简体   繁体   English

我应该使用哪个数组/列表?

[英]Which array/list should I use?

I am looking for a list type which implement the following feature (pseudocode): 我正在寻找一个实现以下功能的列表类型(伪代码):

 list.init(5, 2, 6, 9);
 list.add(1) // 2, 6, 9, 1
 list.add(4) // 6, 9, 1, 4
 list.add(8) // 9, 1, 4, 8

Add new element to fixed size list and pop the oldest one. 将新元素添加到固定大小列表并弹出最旧的元素。 I am sorry, I don´t know the name of this concept so I asking you, what the name could be. 对不起,我不知道这个概念的名称,所以我问你,名字是什么。 ;) ;)

My implementation in C++ would be actually this: 我在C ++中的实现实际上是这样的:

std::deque<double> values(4);

void add(double value)
{
    values.pop_front();
    values.push_back(value);
}

Are there any better implementations than mine, maybe alltime fixed size? 有没有比我更好的实现,也许是所有固定大小?

Boost's circular_buffer is what you want. Boost的circular_buffer就是你想要的。

Example of usage: 用法示例:

   boost::circular_buffer<int> buffer(3);
   buffer.push_back(1);
   buffer.push_back(2);
   buffer.push_back(3);
   // now buffer is 1, 2, 3
   buffer.push_back(4);
   // now buffer is 2, 3, 4

Live example 实例

What you want is called circular buffer. 你想要的是循环缓冲区。 There is no such container in the STL, but Boost does have an implementation. STL中没有这样的容器,但Boost确实有一个实现。

If you don't want to pull in huge dependency on Boost, you can quite easily implement a wrapper over either std::array (if the number of element is smallish) or over std::vector . 如果你不想强烈依赖Boost,你可以很容易地在std::array (如果元素的数量很小)或std::vector实现一个包装器。

The wrapper needs to remember the underlying container size and it's current position, like this: 包装器需要记住底层容器大小及其当前位置,如下所示:

template <class T>
class circular_buffer {
    std::size_t current_pos, cursor;
    std::vector<T> storage;

    circular_buffer(std::size_t size):current_pos(0), cursor(0){
        storage.resize(size);
    }

    void push_back(T elem){
        storage[current_pos++] = T;
        if (current_pos == storage.size()){
            current_pos = 0;
        }
    }

    T get_element(){
        if (cursor == storage.size()){
            cursor = 0;
        }
        return storage[cursor++];
    }

};

Note that the example is simplified and doesn't implement things like second template argument if using std::array , or what to do if your cursor and insertion position catch up to each other. 请注意,示例是简化的,如果使用std::array ,则不会实现第二个模板参数,或者如果光标和插入位置相互匹配,可以执行的操作。

I think you can write you own queue with limited interface.like this 我认为你可以用有限的接口编写自己的队列。就像这样

template<class T, class Cont = deque<T> >
class MyQueue: protected queue<T,Cont>
{
public:
    MyQueue(size_type size, const T& t=T())
    {
        while(size--)
        {
            c.push_back(t);
        }
    }

    void pop_push(const value_type& x)
    {
        pop();
        __super::push(x);
    }
};

It's protected inheritance,so you can't change its size. 它是受保护的继承,因此您无法更改其大小。

你可以试试boost的循环缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM