是否有一种简单的方法可以通过C ++中的值获取元素在std::queue
中的位置?
例如:
std::queue<int> numbers;
numbers.push(7);
numners.push(4);
numbers.push(11);
int position = numbers.getPosition(4); //should be 1
答案 0 :(得分:8)
如果要获取元素的索引,则可能应该考虑使用std::deque
容器而不是std::queue
容器 adapter ,如{{3 }}。
如果您出于其他原因仍要坚持使用this other answer容器适配器,则应该知道它确实通过受保护的数据成员{{ 1}}。
您可以从c
派生以便访问基础容器,并使用std::queue
函数模板在该容器中查找具有此类值的元素。然后,只需使用std::find()
返回该元素的位置。
std::queue
如果未找到该元素,则索引将对应于#include <algorithm>
#include <queue>
template<typename T>
class Queue: std::queue<T> {
public:
auto getPosition(const T& val) const {
auto it = std::find(this->c.begin(), this->c.end(), val);
return std::distance(this->c.begin(), it);
}
// ...
};
成员函数返回的索引。
如果存在重复项,则基于size()
的解决方案将返回第一个元素的位置,即找到的第一个元素具有请求的值std::find()
。
答案 1 :(得分:4)
您可以改用std::deque
:
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
<div class="container min-vh-100 d-flex flex-column" id="container">
<!-- header -->
<div class="row align-items-start bg-info" id="header">
<div class="col text-center">
<button type="button" class="btn" id="cancel">✗</button>
<button type="button" class="btn" id="back">↩</button>
</div>
<div class="col text-center">
<h4 id="title">Notebook</h4>
</div>
<div class="col text-center">
<button type="button" class="btn" id="submit">✔</button>
</div>
</div>
<br />
<!-- Screen list show -->
<div class="row" id="screen">
<div class="col-12">
<ul id="list">
</ul>
</div>
</div>
<!-- Note show -->
<div class="row" id="fullnote">
<div class="col-12">
<p id="text">
</p>
</div>
</div>
<!-- textarea -->
<div class="row flex-grow-1">
<div class="col" id="main">
<textarea class="form-control textarea h-100" value="" placeholder="write note" id="note"></textarea>
</div>
</div>
<!-- footer -->
<div class="row align-items-end" id="footer">
<div class="col d-flex justify-content-start" style="padding: 10px; padding-left: 25px;">
<button id="add" class="btn btn-info rounded-circle"><h4 style="padding: 0px; margin: 0px;">+</h4></button>
<button id="delete" class="btn btn-info rounded-circle">🗑</button>
</div>
</div>
</div>
请注意,#include <algorithm>
std::deque<int> names;
names.push_back(7);
names.push_back(4);
names.push_back(11);
auto it = std::find(names.begin(), names.end(), 4);
if(it != names.end())
int distance = it - names.begin();
else
//no element found
使用std::queue
作为默认实现,因此任何操作都与在队列中花费相同的时间。
std::deque
还支持随机访问,因此std::deque
将返回7。它也可以像其他任何队列一样使用:
names[0]
答案 2 :(得分:2)
另一种通用方式是定义以下新容器,该容器是{{ question.render_question }}
的继承,并定义std::queue
和begin()
返回受保护成员end()
的迭代器。
然后,您可以在此容器中使用各种STL算法:
std::queue::c
...是的,众所周知,STL容器没有虚拟析构函数。 通过基类指针破坏此派生类将导致未定义的行为。 因此,我建议当且仅当您确实需要它时,才使用上面的派生类。
对于当前位置问题,可以找到第一个元素的位置,如下所示:
#include <queue>
template<
class T,
class Container = std::deque<T>
>
class Queue : public std::queue<T, Container>
{
public:
using iterator = typename Container::iterator;
using const_iterator = typename Container::const_iterator;
using reverse_iterator = typename Container::reverse_iterator;
using const_reverse_iterator = typename Container::const_reverse_iterator;
iterator begin() noexcept { return this->c. begin(); }
const_iterator begin() const noexcept { return this->c.cbegin(); }
const_iterator cbegin() const noexcept { return this->c.cbegin(); }
iterator end() noexcept { return this->c. end(); }
const_iterator end() const noexcept { return this->c.cend(); }
const_iterator cend() const noexcept { return this->c.cend(); }
reverse_iterator rbegin() noexcept { return this->c. rbegin(); }
const_reverse_iterator rbegin() const noexcept { return this->c.crbegin(); }
const_reverse_iterator crbegin() const noexcept { return this->c.crbegin(); }
reverse_iterator rend() noexcept { return this->c. rend(); }
const_reverse_iterator rend() const noexcept { return this->c.crend(); }
const_reverse_iterator crend() const noexcept { return this->c.crend(); }
};
答案 3 :(得分:2)
您还可以使用these answers提出的以下功能来访问基础受保护成员std::queue::c
:
#include <queue>
template <class ADAPTER>
const auto& get_container(ADAPTER& a)
{
struct hack : private ADAPTER {
static auto& get(ADAPTER& a) {
return a.*(&hack::c);
}
};
return hack::get(a);
}
然后,您可以按以下方式获取元素的索引。
此功能也可以应用于其他容器适配器std::stack
和std::priority_queue
:
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
std::queue<int> q;
q.push(7);
q.push(4);
q.push(11);
auto& c = get_container(q);
const auto it = std::find(c.cbegin(), c.cend(), 4);
const auto position = std::distance(c.cbegin(), it);
std::cout << "Position is " << position << "." <<std::endl;
return 0;
}