如何在文件中存储泛型树? 我有一个通用的树实现,用C++编写,可以存储任何类型(int,浮点,字符串等)< /p>
例如,假设我有一个输入树A(B(C))(节点A有B作为子节点,B有C作为子节点)。根据规则文件,我的程序给我这个树X(Y(Z))。我的问题是:如何将规则集保存到文件中?如何在此文件中存储树类型?我正在考虑使用XML来存储规则,如下所示如何在文件中存储泛型树? 我有一个通用的树实现,用C++编写,可以存储任何类型(int,浮点,字符串等)< /p>,c++,tree,store,generic-programming,C++,Tree,Store,Generic Programming,例如,假设我有一个输入树A(B(C))(节点A有B作为子节点,B有C作为子节点)。根据规则文件,我的程序给我这个树X(Y(Z))。我的问题是:如何将规则集保存到文件中?如何在此文件中存储树类型?我正在考虑使用XML来存储规则,如下所示 <translationUnit> <from> <A> <B> <C></C> </B> </A> &
<translationUnit>
<from>
<A>
<B>
<C></C>
</B>
</A>
</from>
<to>
<X>
<Y>
<Z></Z>
</Y>
</X>
<to>
</translationUnit>
但是如何存储类类型呢?我猜您使用指针来表示节点之间的关系。比如:
class node{
int value;
node* first_child;
node* next_sibling;
};
class node2{
int value;
int id_first_child;
int id_next_sibling;
};
可以使用索引而不是指针创建序列化节点。比如:
class node{
int value;
node* first_child;
node* next_sibling;
};
class node2{
int value;
int id_first_child;
int id_next_sibling;
};
现在你可以把树弄平了。意思是把它变成数组
将所有节点指针添加到向量
,并将用于将指针转换到向量中索引的映射添加到映射
现在,使用索引而不是指针将节点写入文件
当您从文件中读取时,您需要反向执行,并将索引转换为指针。对于树中的每个值,您应该关联一个类型。所以树中的每个元素都是一对值和值的类型,以及一个子元素列表。在文件中,必须为每个节点存储此信息
可以考虑JSON存储树的序列化版本,它易于阅读,并且有很多优秀的C++库存在。例如,输入树将是:
{
type: "A",
value: "value of the first node,
children: [
{
type: "B"
value: "a value ...",
children: [
{
type: "C",
value: "a value ...",
}
]
}
]
}
您的结果将是:
{
type: "X",
value: "value of the first node,
children: [
{
type: "Y"
value: "a value ...",
children: [
{
type: "Z",
value: "a value ...",
}
]
}
]
}
在配置文件中,您可以存储每个类型转换:
[
{ from: "A", to: "X" },
{ from: "B", to: "Y" },
{ from: "C", to: "Z" }
]
如果您想在类型a的树中存储类型B的子节点,那么使用接口,a和B应该共享一个基类型,并且应该使用指针来存储节点成员。如果不想手动管理,请使用唯一的\u ptr:
unique_ptr<T> node;
唯一的ptr节点;
之后,你有一个指向树的指针列表的指针,需要管理很多指针,如果你想避免指向列表的指针,你可以使用它来允许不完整类型的容器。之后,您不需要在列表中存储指向树的指针,树值将完成此任务
boost::container::list<Tree<T> > children;
boost::container::列出子项;
您应该使用一些序列化库,如Apache thrift或Google Protobuf。但是树作为一种数据类型可能不受支持,因此您需要解决这个问题。但让它们为模板类工作将是一个真正的问题:(我正在考虑使用XML来存储规则,但如何存储类类型呢?”对于XML,你需要有一种鉴别器,不管是元素名还是枚举值。BTW,你应该考虑使用智能指针而不是代码>树*< /Cord> ET.al.忘记将规则存储在文件中。你会用R做什么?当你从一个文件中加载它们时,假设你将有一个名为“MyStfOfStices”或SoMeSuCh的C++对象。你会如何使用它?你有一个接口吗?你可以定义一个序列化协议(作为特征),那些要序列化的类型必须实现。@π-Youth-To-αῥεῖ 什么是智能指针?使用您的解决方案,如何将指针转换为int?您是否也需要存储映射?还要注意,我不需要存储指针,我可以在加载文件时重建树否,树通常不是以这种方式存储的。这将相当浪费程序员的精力。相反,树通常是递归存储的例如,(root[child1,child2,…childN])
,其中root
是根节点的值,left
和right
是它的子节点。空树是()
。这只是一个示例,只要您能够区分分隔符,实际格式几乎可以是任何格式(本例中为括号、括号和逗号)从节点值。现在我使用xml来表示sav树,因为存在很多解析器,但你的想法非常好。你的想法很好,但你能解释一下为什么使用unique_ptr和boost list会更好吗?你的答案与json的xml istead一起工作吗?当我阅读你的代码时,我认为T应该是树中所有值的基本类型换句话说,你的树只会是一棵T树,这意味着一棵a树不能有一棵B树的子树。你在这里需要一个多态类型,如果你有多态类型,你应该使用指针,如果你有指针,唯一指针很适合应用RAII。boost::container::list在这里是为了避免一个指向列表的原始指针。O当然,你可以使用xml而不是json,这只是序列化格式。我接受你的答案不仅是因为它是完整的,还因为你给了我关于unique_ptr和boost list的提示