- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在寻找一种方法来为每个节点具有任意数量子节点的树建模。
这个答案建议使用 Boost Graph Library 来完成这个任务:
What's a good and stable C++ tree implementation?
我需要执行的主要操作是树及其子树的遍历函数(前序、子树、叶子)。我还需要从 child 向上收集数据的功能。
BGL 是正确的选择吗?如何实现简单树的先序遍历?在文档中,我只能找到有关常规图表的信息。
编辑:我也知道 tree.hh
库,但它的许可证似乎并不适合所有人。
最佳答案
我已经对这棵树进行了改进。顶点和边迭代器现在都包含在外观中。如果我做出更多重大更改,我会发布它们。我曾在一个小型项目中使用过 tree.hh,但并不十分喜欢它。我会用这个替换它,看看它还需要什么。
#include<iostream>
#include <string>
#include <boost/shared_ptr.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/visitors.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/graph_utility.hpp>
// ..............................................
template< typename Tree >
void write_graphviz( std::ostream& os, Tree tree )
{
os << "digraph G {\n";
for( auto it : tree )
os << it << "[label=\"" << tree[ it ] << "\"];\n";
for( auto it : tree.get_edges( ) )
os << it.m_source << "->" << it.m_target << ";\n";
os << "}\n";
}
// ..............................................
template< typename Tree >
const typename boost::graph_traits< Tree >::vertex_descriptor get_vertex( Tree& tree, const typename Tree::out_edge_iterator& iter ) { return iter->m_target; }
template< typename Tree >
const typename boost::graph_traits< Tree >::vertex_descriptor get_vertex( Tree& tree, const typename Tree::vertex_iterator& iter ) { return *iter; }
// ..............................................
template< typename Tree, typename IteratorType >
class tree_iter_type
: public boost::iterator_facade<
tree_iter_type< typename Tree, typename IteratorType >
,typename Tree::vertex_property_type
,boost::forward_traversal_tag
>
{
public:
typedef typename tree_iter_type< typename Tree, typename IteratorType > other_type;
typedef typename boost::graph_traits< Tree >::vertex_descriptor iterator_value_type;
typedef typename boost::graph_traits< Tree >::edge_descriptor eiterator_value_type;
typedef typename Tree::vertex_property_type value_type;
private:
friend class boost::iterator_core_access;
value_type& dereference( ) const { return tree[ get_vertex( tree, iter ) ]; }
void increment( ) { ++iter; }
bool equal( other_type const& other ) const { return iter == other.iter; }
public:
tree_iter_type( Tree& tree, IteratorType iter ) : tree( tree ), iter( iter ) { }
//http://stackoverflow.com/questions/31264984/c-compiler-error-c2280-attempting-to-reference-a-deleted-function-in-visual
other_type& operator=( other_type const& a ){ tree= a.tree, iter= a.iter; return *this; };
iterator_value_type vertex( ) { return get_vertex( tree, iter ); }
//how to make this work? It blows things up....
//iterator_value_type operator ( ) { return get_vertex( tree, iter ); }
private:
Tree& tree;
IteratorType iter;
};
// ..............................................
template< typename Tree, typename IterType > //proxy container
class tree_pair_type
{
public:
typedef typename boost::graph_traits< Tree >::vertex_descriptor vertex_t;
typedef std::pair< IterType, IterType > iterator_pair_t;
tree_pair_type( iterator_pair_t pair ) :pair( pair ){ }
IterType begin( ) { return pair.first; }
IterType end( ) { return pair.second; }
private:
iterator_pair_t pair;
};
// ..............................................
template< typename ValueType >
class BGTree
{
public:
typedef boost::adjacency_list<
boost::mapS,
boost::vecS,
boost::bidirectionalS,
ValueType >
tree_t;
typedef typename ValueType value_type;
typedef typename boost::graph_traits< tree_t >::vertex_descriptor vertex_t;
typedef typename boost::graph_traits< tree_t >::edge_descriptor edge_t;
typedef typename tree_t::vertex_iterator vertex_iterator;
typedef typename tree_t::edge_iterator edge_iterator;
typedef typename tree_t::out_edge_iterator out_edge_iterator;
typedef typename tree_iter_type< tree_t, typename tree_t::out_edge_iterator > out_tree_iterator;
typedef typename tree_iter_type< tree_t, typename tree_t::vertex_iterator > vertex_tree_iterator;
typedef tree_pair_type< tree_t, edge_iterator > pair_type;
typedef tree_pair_type< tree_t, out_tree_iterator > out_pair_type;
typedef tree_pair_type< tree_t, vertex_tree_iterator > vertex_pair_type;
//get children
auto make_out_iterator( vertex_t pos ) { return out_tree_iterator( tree, boost::out_edges( pos, tree ).first ); }
auto make_out_iterator_end( vertex_t pos ) { return out_tree_iterator( tree, boost::out_edges( pos, tree ).second ); }
//get sub tree
auto make_range_iterator( vertex_t pos ) { return vertex_tree_iterator( tree, begin( ) ); }
auto make_range_iterator_end( vertex_t pos ) { return vertex_tree_iterator( tree, end( ) ); }
public:
BGTree( const ValueType& root )
:root( boost::add_vertex( root, tree ) ) { }
vertex_t get_root( ) const { return root; }
vertex_t add_child( const ValueType& item, vertex_t where ) {
auto temp= boost::add_vertex( item, tree );
boost::add_edge( where, temp, tree );
return temp;
}
vertex_t get_parent( vertex_t from ) const { return boost::in_edges( from, tree ).first->m_source; }
auto get_bundle( ) { return boost::get( vertex_bundle, tree ); }
//vertext set, not by value
vertex_iterator begin( ) { return boost::vertices( tree ).first; }
vertex_iterator end( ) { return boost::vertices( tree ).second; }
ValueType& operator [ ] ( vertex_t at ) { return tree[ at ]; }
//by index, not by value
auto get_edges( ) { return pair_type( boost::edges( tree ) ); }
auto get_children( vertex_t pos= 0 ) {
return out_pair_type( std::make_pair(
make_out_iterator( pos ), make_out_iterator_end( pos ) ) );
}
auto breadth_first( vertex_t pos= 0 ) {
return vertex_pair_type( std::make_pair(
make_range_iterator( pos ), make_range_iterator_end( pos ) ) );
}
auto get_vertex_children( vertex_t pos ) { return out_pair_type( boost::out_edges( pos, tree ) ); }
auto get_boost_graph_tree( ) { return tree; }
private:
tree_t tree;
vertex_t root;
};
// .....................................................................................
// .....................................................................................
int main( )
{
//build tree to match the images in documentation
//https://en.wikipedia.org/wiki/Tree_traversal
typedef BGTree< char > char_tree_t;
char_tree_t tree( 'F' );
auto last= tree.get_root( );
last= tree.add_child( 'B' , last );
tree.add_child( 'A' , last );
last= tree.add_child( 'D' , last );
tree.add_child( 'C' , last );
tree.add_child( 'E' , last );
last= tree.get_root( );
last= tree.add_child( 'G' , last );
last= tree.add_child( 'I' , last );
last= tree.add_child( 'H' , last );
// visualization
std::ofstream os( "./graph.dot" );
::write_graphviz( os, tree );
std::cout << "Pre-order: F, B, A, D, C, E, G, I, H\n";
for( auto& i : tree.breadth_first( ) )
std::cout << i << " ";
std::cout << "\n\n";
std::cout << "Children of root: B, G\n";
for( auto& i : tree.get_children( ) )
std::cout << i << " ";
std::cout << "\n\n";
auto it= std::find_if(
tree.breadth_first( ).begin( ), tree.breadth_first( ).end( ),
[ ] ( const char& test ) { return test == 'B'; } );
std::cout << "should be 'B', find_if: " << *it << "\n\n";
std::cout << "children of 'B' from iterator: A D\n";
//as it has a referance to tree, could be it.get_children( )?
for( auto& item : tree.get_children( it.vertex( ) ) )
std::cout << item << " ";
std::cout << "\n\n";
return 0;
}
关于c++ - 在 C++ 中建模任意树(使用迭代器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40809926/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!