Push_Front Pop_Back for C ++ Vector

时间:2016-02-11 22:01:13

标签: c++ vector

我正在尝试保留一个命令向量,以便最近保留10个命令。我有一个push_back和一个pop_back,但是如何在不转换for循环中的所有内容的情况下删除最旧的?擦除是唯一的方法吗?

4 个答案:

答案 0 :(得分:3)

使用std::deque这是一个类似矢量的容器,擅长于两端的移除和插入。

答案 1 :(得分:3)

如果您愿意使用提升功能,我建议您查看circular_buffer,它可以非常有效地处理这个确切的问题(避免不必要地移动元素,而只是操纵一对指针):

 // Create a circular buffer with a capacity for 3 integers.
 boost::circular_buffer<int> cb(3);

 // Insert threee elements into the buffer.
 cb.push_back(1);
 cb.push_back(2);
 cb.push_back(3);
 cb.push_back(4);
 cb.push_back(5);

最后两个操作只是覆盖前两个元素。

答案 2 :(得分:2)

在向量周围编写一个包装器,为自己提供一个循环缓冲区。像这样:

include <vector>

/**

  Circular vector wrapper

  When the vector is full, old data is overwritten

*/
class cCircularVector
{
public:

    // An iterator that points to the physical begining of the vector
    typedef std::vector< short >::iterator iterator;
    iterator begin() { return myVector.begin(); }
    iterator end() { return myVector.end(); }

    // The size ( capacity ) of the vector
    int size() { return (int) myVector.size(); }

    void clear() { myVector.clear(); next = 0; }

    void resize( int s ) { myVector.resize( s ); }

    // Constructor, specifying the capacity
    cCircularVector( int capacity )
    : next( 0 )
    {
        myVector.resize( capacity );
    }

    // Add new data, over-writing oldest if full
    void push_back( short v )
    {
        myVector[ next] = v;
        advance();
    }

    int getNext()
    {
        return next;
    }

private:

    std::vector< short > myVector;
    int next;

    void advance()
    {
        next++;
        if( next == (int)myVector.size() )
            next = 0;

    }
};

答案 3 :(得分:1)

这样的事情:

http://ideone.com/SLSNpc

注意:它只是一个基础,你仍然需要对它进行一些工作。这个想法是它易于使用,因为它有自己的迭代器,它可以为你提供所需的输出。正如您所看到的那样,插入的最后一个值是首先显示的值,我猜是你想要的。

#include <iostream>
#include <vector>

template<class T, size_t MaxSize>
class TopN
{
public:
    void push_back(T v)
    {
        if (m_vector.size() < MaxSize)
            m_vector.push_back(v);
        else
            m_vector[m_pos] = v;

        if (++m_pos == MaxSize)
            m_pos = 0;
    }

    class DummyIterator
    {
    public:
        TopN &r; // a direct reference to our boss.
        int p, m; // m: how many elements we can pull from vector, p: position of the cursor.

        DummyIterator(TopN& t) : r(t), p(t.m_pos), m(t.m_vector.size()){}

        operator bool() const { return (m > 0); }

        T& operator *()
        {
            static T e = 0; // this could be removed
            if (m <= 0) // if someone tries to extract data from an empty vector
                return e; // instead of throwing an error, we return a dummy value

            m--;

            if (--p < 0)
                p = MaxSize - 1;

            return r.m_vector[p];
        }
    };

    decltype(auto) begin() { return m_vector.begin(); }
    decltype(auto) end() { return m_vector.end(); }

    DummyIterator get_dummy_iterator()
    {
        return DummyIterator(*this);
    }
private:
    std::vector<T> m_vector;
    int m_pos = 0;
};

template<typename T, size_t S>
void show(TopN<T,S>& t)
{
    for (auto it = t.get_dummy_iterator(); it; )
        std::cout << *it << '\t';

    std::cout << std::endl;
};

int main(int argc, char* argv[])
{
    TopN<int,10> top10;
    for (int i = 1; i <= 10; i++)
        top10.push_back(5 * i);

    show(top10);

    top10.push_back(60);
    show(top10);

    top10.push_back(65);
    show(top10);

    return 0;
}