如何在文件中存储通用树?

时间:2014-02-23 16:35:24

标签: c++ tree store generic-programming

我有一个用C ++编写的通用树实现,可以存储任何类型(int,float,string等)

template<class T> class Tree {
public:
// Class interface
private:
T node;
std::list<Tree<T>*>* children;
};

我有一个程序(用C ++编写),它将源树作为输入,并根据一组规则(存储在文件中)输出另一个树。

Any instance of class A become an instance of class X
Any instance of class B become an instance of class Y
Any instance of class C become an instance of class Z

例如,假设我有这个输入树A(B(C))(节点A有B作为子节点而B有C作为子节点)。根据规则文件我的程序给我这个树X(Y(Z))。我的问题是:如何在文件中保存规则集?如何将树类型存储在此文件中?我想用XML来存储规则,比如这个

<translationUnit>
  <from>
    <A>
      <B>
        <C></C>
      </B>
    </A>
  </from>
  <to>
    <X>
      <Y>
        <Z></Z>
      </Y>
    </X>
  <to>
</translationUnit>

但是如何存储类类型?

2 个答案:

答案 0 :(得分:0)

我猜你使用指针来表示节点之间的关系。类似的东西:

class node{
 int value;
 node* first_child;
 node* next_sibling;
};

您可以使用索引而不是指针创建序列化节点。类似的东西:

class node2{
     int value;
     int id_first_child;
     int id_next_sibling;
};

现在你可以平放树了。意味着把它变成阵列。

将所有节点指针添加到vector<node*>,并添加到map<node*,int>用于将指针转换为向量中索引的映射。

现在使用索引而不是指针将节点写入文件。

当您从文件中读取时,您需要相反地执行此操作,并将索引转换为指针。

答案 1 :(得分:0)

对于树中的每个值,您应该关联一个类型。因此,树中的每个元素都是一对值的类型和值以及子列表。在您的文件中,您必须为每个节点存储此信息。

你可以考虑让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" }
]

如果要将类型B的子项存储在类型A的树中,并使用您的接口,则A和B应共享基类型,并且应使用指针来存储节点成员。如果您不想手动管理它,请使用unique_ptr:

unique_ptr<T> node;

之后,你有一个指向树指针列表的指针,它是很多指向要管理的指针,如果你想避免指向列表的指针,你可以使用允许容器不完整的boost::container::list类型。之后,您不需要指向存储在列表中的树的指针,Tree值将完成这项工作。

boost::container::list<Tree<T> > children;