元素如何在vector中找到自己的索引?
How can an element find its own index in a vector?
我正在尝试使用std::unique_ptr
重新实现树数据结构,其想法是父节点将拥有其子节点,这些子节点存储在unique_ptr
的向量中。
由于接口的原因,我需要一个节点销毁自己的方法。在这种情况下,我认为节点应该将自己从父节点的子向量中擦除。
下面的实现"工作"(在c++11编译器中),但是它丑得要命,我确信这是处理这个问题的次优方法。
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
struct Node {
typedef std::vector<std::unique_ptr<Node>> vec_node_uptr;
unsigned id;
Node* parent;
vec_node_uptr child_nodes;
// ctor
Node(unsigned id): id(id){ parent = nullptr; }
void add_child(Node* new_child){
new_child -> parent = this;
child_nodes.push_back( std::unique_ptr<Node>(std::move(new_child) ) );
}
int where_am_i(){
int result_ = 0;
for(auto& i: this -> parent -> child_nodes) {
if (this == i.get()) {
return result_;
} else {
result_++;
}
}
}
void suicide(){
parent -> child_nodes.erase(parent -> child_nodes.begin()+ where_am_i());
}
};
int main()
{
std::unique_ptr<Node> root(new Node(0));
root -> add_child(new Node(1));
root -> add_child(new Node(2));
root -> child_nodes[0] -> add_child(new Node(3));
root -> child_nodes[0] -> add_child(new Node(4));
root -> child_nodes[1] -> add_child(new Node(5));
root -> child_nodes[1] -> add_child(new Node(6));
root -> child_nodes[1] -> suicide();
return 0;
}
有什么建议吗?也许用std::find
?
您可以使用find_if和lambda:
更优雅地解决这个问题void suicide()
{
auto& parentsChildren = parent->child_nodes;
parentsChildren.erase(find_if(begin(parentsChildren), end(parentsChildren),
[&](const unique_ptr<Node>& node) { return node.get() == this; }));
}
如果您希望当前数据结构具有恒定时间的where_am_i()
,则需要在节点本身中存储索引或迭代器。这是(a)重复的,并且(b)将导致进一步的复杂性,因为每当您删除不是其父节点的最后一个子节点时,您将需要更新所有后续子节点的索引/迭代器…
然而,创建一个恒定时间的where_am_i()
可能没有真正的优势,因为从vector中删除一个元素无论如何都是O(n),除非你总是从末尾(或接近末尾)删除。
但是,如果您通常会从末尾删除,并且如果从来没有必要将一组子节点的所有权从父节点转移,那么这里有一个替代的,更简单的设计,避免了在每个节点中存储索引或迭代器的需要:
c++标准保证std::vector
像数组一样在内存中连续地布局它们的内容。因此,如果child_nodes
向量实际上是按值存储它的元素——即,如果它被声明为
typedef std::vector<Node> vec_node_uptr;
vec_node_uptr child_nodes;
则可以通过简单地从给定元素的地址中减去向量中第一个元素的地址,让指针算法为您进行除法,从而在常数时间内找到位置:
size_t where_am_i() {
return this - &parent->child_nodes[0];
}
相关文章:
- 没有为自己的结构调用列表推回方法
- 查找最接近的大于当前数字的数字的索引
- 在C++中调整向量中的索引
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 将转换字符键入 int 以用作向量C++的索引
- C++从对象自己的类中删除对象
- 使用 std::optional,而不是自己的结构
- 在对向量中查找元素的索引
- 为什么我的 if else 语句不起作用并从数组中输出正确的索引?
- 如何检查类实例向量的索引是否为空
- 子轴围绕父轴而不是他自己的轴旋转
- 当该数组的索引中没有元素时,指针指向什么?
- C++17:如何在并行 STL 中获取工作项的索引
- 为什么提升图库的 read_graphviz() 函数会改变节点的索引
- 如何在 STL 函数中找到传递给谓词的元素的索引?
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- C++ 如何为自己的迭代器类从迭代器转换为const_iterator?
- 元素如何在vector中找到自己的索引?
- 如何使我自己的容器索引和可分配