在某次项目中,需要遍历装配体,装配体中可能含有嵌套,需要用到一中数据结构,类似于二叉树,但节点数量可能大于2,
如下图:
最终需要处理出来的结果如下:
定义树结构如下来存储每个节点的信息,主要结构如下:
1 class TreeNode 2 { 3 string name; 4 vector<TreeNode*> children;//子节点 5 TreeNode* parent;//父节点 6 }
使用递归来解析,用容器map来存储最后的结果。
完整代码如下:
1 #include <vector> 2 #include <string> 3 #include <map> 4 using namespace std; 5 typedef map<string,unsigned> DataMap; 6 enum NodeType //节点类型 7 { 8 UnknownNode,//未知 9 TopAsmNode,//装配体 10 SubAsmNode,//子装配体 11 FileNode,//文件夹 12 PartNode //零件 13 }; 14 15 class FileData 16 { 17 private: 18 string name; 19 DataMap dataMap; 20 public: 21 FileData(){} 22 FileData(string s) 23 { 24 name = s; 25 } 26 string GetName() 27 { 28 return name; 29 } 30 DataMap GetDataMap() 31 { 32 return dataMap; 33 } 34 void AddPart(string s) 35 { 36 DataMap::iterator i = dataMap.find(s); 37 if(i!=dataMap.end()) 38 { 39 if(i->first==s) 40 ++( i->second ); 41 } 42 else 43 dataMap.insert(pair<string,unsigned>(s,1)); 44 } 45 }; 46 47 class NodeDataVec 48 { 49 private: 50 vector<FileData> FileDataVec; 51 public: 52 vector<FileData> GetFileData() 53 { 54 return FileDataVec; 55 } 56 void AddFileNode(string s) 57 { 58 FileData node(s); 59 FileDataVec.push_back(node); 60 } 61 FileData *FindFileNode(string s) 62 { 63 for(unsigned i = 0;i<FileDataVec.size();++i) 64 { 65 if(FileDataVec[i].GetName() == s) 66 return &FileDataVec[i]; 67 } 68 return NULL; 69 } 70 71 NodeDataVec(){}; 72 ~NodeDataVec(){}; 73 }; 74 75 class TreeNode 76 { 77 private: 78 NodeType nodeType; 79 vector<TreeNode*> children;//子节点 80 TreeNode* parent;//父节点 81 string name; 82 public: 83 void AnalyzeData(NodeDataVec &data) 84 { 85 for(unsigned i=0;i<children.size();++i) 86 { 87 switch (children[i]->GetNodeType()) 88 { 89 case TopAsmNode: 90 children[i]->AnalyzeData(data); 91 break; 92 case SubAsmNode: 93 children[i]->AnalyzeData(data); 94 break; 95 case FileNode: 96 if(data.FindFileNode(children[i]->GetName())!=NULL)//已经含有该文件夹节点 97 { 98 children[i]->AnalyzeData(data); 99 } 100 else 101 { 102 data.AddFileNode(children[i]->GetName()); 103 children[i]->AnalyzeData(data); 104 } 105 break; 106 case PartNode: 107 { 108 FileData * fileNode = data.FindFileNode(name); 109 fileNode->AddPart(children[i]->GetName()); 110 } 111 break; 112 default: 113 break; 114 } 115 } 116 117 } 118 void AddChildNode(TreeNode *node) 119 { 120 children.push_back(node); 121 node->SetParent(this); 122 } 123 const vector<TreeNode*> GetChildren() 124 { 125 return children; 126 } 127 const TreeNode* GetParent() 128 { 129 return parent; 130 } 131 const NodeType GetNodeType() 132 { 133 return nodeType; 134 } 135 const string GetName() 136 { 137 return name; 138 } 139 void SetName(string &s) 140 { 141 name = s; 142 } 143 void SetNodeType(NodeType &type) 144 { 145 nodeType = type; 146 } 147 void SetParent(TreeNode* p) 148 { 149 parent = p; 150 } 151 void SetChildren(vector<TreeNode*> &c) 152 { 153 children = c; 154 } 155 TreeNode(string s ,NodeType t) 156 { 157 SetName(s); 158 SetNodeType(t); 159 } 160 TreeNode() 161 { 162 children.clear(); 163 parent = NULL; 164 } 165 ~TreeNode(){} 166 };
测试:
1 int main() 2 { 3 TreeNode asmRoot = TreeNode("TopAsm",TopAsmNode); 4 TreeNode asmSub01 = TreeNode("asmSub01", SubAsmNode); 5 TreeNode asmSub02 = TreeNode("asmSub02", SubAsmNode); 6 TreeNode fileNode01 = TreeNode("工序1", FileNode); 7 TreeNode fileNode01_2 = TreeNode("工序1", FileNode); 8 TreeNode fileNode02 = TreeNode("工序2", FileNode); 9 TreeNode part01 = TreeNode("partA", PartNode); 10 TreeNode part02 = TreeNode("partB", PartNode); 11 TreeNode part03 = TreeNode("partC", PartNode); 12 TreeNode part04 = TreeNode("partD", PartNode); 13 14 fileNode01.AddChildNode(&part01); 15 fileNode01.AddChildNode(&part03); 16 17 fileNode02.AddChildNode(&part04); 18 19 fileNode01_2.AddChildNode(&part01); 20 fileNode01_2.AddChildNode(&part02); 21 22 asmSub01.AddChildNode(&fileNode01); 23 asmSub01.AddChildNode(&fileNode02); 24 asmSub02.AddChildNode(&fileNode01_2); 25 26 asmRoot.AddChildNode(&asmSub01); 27 asmRoot.AddChildNode(&asmSub02); 28 29 NodeDataVec data; 30 asmRoot.AnalyzeData(data); 31 32 return 0; 33 }