使用 ranges-v3 实现 DFS
Using ranges-v3 to implement DFS
我对使用 range-v3 构建和查询线性四叉树数据结构很感兴趣。我已经能够成功地使用 range-v3 使用库中的现有视图构建线性四叉树数据结构。我很高兴能够将查询逻辑表示为视图适配器,因为您可以通过推进派生范围的 RandomAccessIterator 来迭代四叉树中的节点,这很方便地帮助将查询行为与四叉树的结构分开。
我的视图适配器只有一个参数:用户定义的 lambda 谓词函数,用于评估节点并确定是单步执行还是单步执行。单步执行会导致评估子节点,而单步执行会导致访问下一个同级节点(或可能是节点的父级的下一个同级节点),直到成功评估叶节点或我们通过根节点"退出"。(可以将其视为 DFS 模式。
因此,我们能够根据 RandomAccessIterator(来自派生范围)和 Sentinel(而不是另一个迭代器)来定义此范围。
下面是一些显示整体结构的精简代码。(如果缺少会员数据/结构,我深表歉意):
template<typename Rng, typename Fun>
class quadtree_query_view
: public ranges::view_adaptor<quadtree_query_view<Rng, Fun>, Rng>
{
friend ranges::range_access;
using base_iterator_t = ranges::iterator_t<Rng>;
ranges::semiregular_t<Fun> fun;
uint tree_depth;
struct query_termination_adaptor : public ranges::adaptor_base
{
query_termination_adaptor() = default;
query_termination_adaptor(uint tree_depth) : tree_depth(tree_depth) {};
uint tree_depth;
uint end(quadtree_query_view const&) {
return tree_depth;
}
};
struct query_adaptor : public ranges::adaptor_base
{
query_adaptor() = default;
query_adaptor(ranges::semiregular_t<Fun> const& fun) : fun(fun) {};
ranges::semiregular_t<Fun> fun;
bool exited = false;
uint current_node_depth = 0;
base_iterator_t begin(quadtree_query_view const& rng) {
return ranges::begin(rng.base());
}
// TODO: implement equal?
// TODO: implement empty?
auto read(base_iterator_t const& it) const
{
return *it; // I'm not concerned about the value returned by this range yet.
}
CONCEPT_REQUIRES(ranges::RandomAccessIterator<base_iterator_t>())
void next(base_iterator_t& it ){
if (fun(*it)) { // Step in
// Advance base iterator (step in)
// Increment current_node_depth
} else { // Step out
// Advance base iterator (step out)
// Set "exited = true" if stepping out past root node.
// Decrement current_node_depth
}
}
};
public:
quadtree_query_view() = default;
quadtree_query_view(Rng&& rng, uint tree_depth, Fun fun)
: quadtree_query_view::view_adaptor{std::forward<Rng>(rng)}
, tree_depth(tree_depth)
, fun(std::move(fun))
{}
query_adaptor begin_adaptor() const {
return {std::move(fun)};
}
query_termination_adaptor end_adaptor() const {
return {tree_depth};
}
};
我正在尝试找出完成此实现的最后几个步骤:
我的范围不符合
Range
概念WeaklyEqualityComparable
因为我的迭代器/哨兵对没有实现要求。这样做的最佳方法是什么?我是否需要为
query_adaptor
实现equal
成员方法?两个迭代器参数对应于什么?我假设我需要为
query_adaptor
实现empty
成员方法。这是查询退出条件逻辑的位置吗?根据文档,段参数需要是与哨兵关联的类型。这是否与query_termination_adaptor::end()
返回的类型相同,例如uint
?还是这需要另一种类型?
感谢您分享任何见解。看到范围被纳入 C++20,我真的很兴奋!
啊。
我能够通过使用default_sentinel
来解决我的问题。由于query_adaptor
旨在从根节点开始并沿单个方向迭代,因此我可以删除end_adaptor
并一起query_termination_adaptor
。我只需要为适配器实现一个bool equal(default_sentinel) const { ... }
方法,在那里我能够确定是否满足查询退出条件。
我仍然不确定为什么尝试实现自定义哨兵类型会给我带来问题。但是,除了拥有tree_depth
之外,它没有提供超过default_sentinel
的任何附加功能。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误
- 在C++中实现 DFS 时出现分段错误
- 在C++中实现图形 DFS,指针问题
- 使用 ranges-v3 实现 DFS
- 我不理解这个dfs实现的语法
- 算法实现错误(DFS)
- 实现迷宫树以在DFS,BFS中使用
- 用DFS c++实现一个从邻接表到边表的图
- 使用矢量的dfs实现给出了segfault