【问题标题】:C++ N-last added items containerC++ N-last added items 容器
【发布时间】:2020-02-04 19:01:17
【问题描述】:

我尝试为下一个简单任务找到最佳数据结构:将 N 个最后添加的项目值保存在内置容器中的类。如果对象获得 N+1 项,则应将其添加到容器的末尾,并应从中删除第一项。它就像一个简单的队列,但类应该有一个 GetAverage 方法,以及其他必须可以访问每个项目的方法。不幸的是,std::queue 没有用于此目的的方法 beginend

它是简单类接口的一部分:

class StatItem final
{
    static int ITEMS_LIMIT;

public:
    StatItem() = default;
    ~StatItem() = default;

    void Reset();
    void Insert(int val);

    int  GetAverage() const;

private:
    std::queue<int> _items;
};

以及所需实现的一部分:

void StatItem::Reset()
{
    std::queue<int> empty;
    std::swap(_items, empty);
}

void StatItem::Insert(int val)
{
    _items.push(val);
    if (_items.size() == ITEMS_LIMIT)
    {
        _items.pop();
    }
}

int StatItem::GetAverage() const
{
    const size_t itemCount{ _items.size() };
    if (itemCount == 0) {
        return 0;
    }

    const int sum = std::accumulate(_items.begin(), _items.end(), 0); // Error. std::queue doesn't have this methods
    return sum / itemCount;
}

有什么想法吗?

我不确定 std::deque。它是否有效,我应该将它用于此任务还是其他不同的任务?

P.S.:在我的情况下,ITEMS_LIMIT 大约 100-500 个项目

【问题讨论】:

  • std::deque 就足够了。您还可以在找到前 N 个项目的平均值后,在恒定时间内找到所有项目的平均值。技巧是当您弹出一个元素时,从当前总数中减去它的值,然后将要推入的新元素的值添加到当前总数中。项目总数仍为 N。
  • 您可以使用std::deque 并在每次插入和删除项目时保持总和。
  • 看来你想要一个循环缓冲区。
  • @Jarod42 现在看来我可以使用带有附加索引的简单 std::array 我应该在哪个位置更改值

标签: c++ stl


【解决方案1】:

您正在寻找的数据结构是一个循环缓冲区。 Boost 库中有一个实现,但是在这种情况下,因为您似乎不需要删除项目,您可以使用 std::vectorstd::array 轻松实现一个。

到目前为止,您需要跟踪向量中的元素数量,以便在达到元素限制之前正确平均,以及当您达到该限制时应该换行的当前插入索引。

使用数组或向量将使您受益于具有固定元素限制,因为元素将存储在单个内存块中(有利于快速内存访问),并且您可以使用这两种数据结构为施工所需的所有元素。

如果您选择使用std::vector,请确保使用“填充”构造函数 (http://www.cplusplus.com/reference/vector/vector/vector/),这将允许您从一开始就创建正确数量的元素并避免任何额外的分配。

【讨论】:

  • 感谢您的回答和提示。最终,我在 std::array 上使用附加索引变量实现了它。并感谢循环缓冲区提示,我以前不知道它
猜你喜欢
  • 1970-01-01
  • 2011-05-10
  • 2016-01-15
  • 2018-10-07
  • 2019-10-21
  • 2014-07-29
  • 2017-02-26
  • 1970-01-01
  • 2020-09-21
相关资源
最近更新 更多