하나의 N-ary 트리가 있고 직렬화 및 역직렬화해야 한다고 가정합니다. 직렬화는 데이터 구조나 개체를 비트 시퀀스로 변환하여 파일이나 메모리 버퍼에 저장할 수 있고 나중에 동일하거나 다른 컴퓨터 환경에서 재구성할 수 있다는 것을 알고 있습니다.
여기서 우리는 N-ary 트리를 직렬화 및 역직렬화하는 알고리즘을 고안해야 합니다. N-ary 트리는 각 노드에 N 이하의 자식이 있는 루트 트리입니다.
따라서 입력이 다음과 같으면

그러면 출력은 Serialize:1 #3 2 4 #5 6 ##### 및 Deserialized Tree:1[3[5, 6, ], 2, 4, ]
가 됩니다.이 문제를 해결하기 위해 다음 단계를 따릅니다. −
-
createVector() 함수를 정의하면 s가 필요합니다.
-
하나의 2D 배열 ret 정의
-
배열 tempv 정의
-
temp :=빈 문자열
-
initialize i :=0의 경우, i
-
s[i]가 공백과 같지 않고 s[i]가 '#'과 같지 않으면 -
-
온도 :=온도 + s[i]
-
-
그렇지 않으면 s[i]가 공백 문자열과 같을 때 -
-
tempv의 끝에 temp 정수 삽입
-
temp :=빈 문자열
-
-
그렇지 않으면 s[i]가 '#'과 같을 때 -
-
ret 끝에 tempv 삽입
-
temp :=빈 문자열
-
클리어 tempv
-
-
-
동안 (ret가 비어 있지 않고 ret의 마지막 요소가 0과 동일), do -
-
ret에서 마지막 요소 삭제
-
-
리턴 렛
-
serialize() 함수를 정의하면 루트가 됩니다.
-
ret :=빈 문자열
-
루트가 아닌 경우 0이 아닌 경우 -
-
리턴 렛
-
-
하나의 대기열 정의 q
-
루트를 q에 삽입
-
rret :=ret 루트의 val 연결
-
ret :=ret 공백 연결
-
ret :=ret "#" 연결
-
동안(q가 비어 있지 않음) -
를 수행합니다.-
curr =q
의 첫 번째 요소 -
q에서 요소 삭제
-
for initialize i :=0, i
-
curr의 자식[i]인 경우 -
-
ret :=ret curr의 자식[i] 연결
-
curr의 자식[i]을 q
에 삽입
-
-
ret :=ret + 빈 문자열
-
-
ret :=ret "#" 연결
-
-
리턴 렛
-
deserialize() 함수를 정의하면 데이터가 필요합니다.
-
데이터 크기가 0과 같으면 -
-
null 반환
-
-
하나의 2D 배열 정의 v :=createVector(data)
-
ret :=값이 v[0, 0]인 새 노드
-
하나의 대기열 정의 q
-
q에 ret 삽입
-
나는 :=1
-
동안(q가 비어 있지 않고 i - v의 크기가 아님), 다음을 수행합니다. -
-
curr =q
의 첫 번째 요소 -
q에서 요소 삭제
-
초기화 j :=0일 때 j − v[i]의 크기, 업데이트(j를 1만큼 증가), −
-
노드 :=v[i, j]
-
temp =값 노드가 있는 새 노드
-
curr의 자식 끝에 temp 삽입
-
q에 temp 삽입
-
-
(i를 1씩 증가)
-
-
리턴 렛
예시
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) {
val = _val;
}
Node(int _val, vector<Node*> _children) {
val = _val;
children = _children;
}
};
string n_ary_to_str(Node *root){
string ret = "";
if(root){
ret = ret + to_string(root->val);
if(root->children.size() > 0){
ret += "[";
for(Node* child : root->children){
ret += n_ary_to_str(child) + ", ";
}
ret += "]";
}
}
return ret;
}
class Codec {
public:
vector<vector<int>>createVector(string s) {
vector<vector<int>> ret;
vector<int> tempv;
string temp = "";
for (int i = 0; i < s.size(); i++) {
if (s[i] != ' ' && s[i] != '#') {
temp += s[i];
}
else if (s[i] == ' ') {
tempv.push_back(stoi(temp));
temp = "";
}
else if (s[i] == '#') {
ret.push_back(tempv);
temp = "";
tempv.clear();
}
}
while (!ret.empty() && ret.back().size() == 0)
ret.pop_back();
return ret;
}
string serialize(Node *root) {
string ret = "";
if (!root)
return ret;
queue<Node *> q;
q.push(root);
ret += to_string(root->val);
ret += " ";
ret += "#";
while (!q.empty()) {
Node *curr = q.front();
q.pop();
for (int i = 0; i < curr->children.size(); i++) {
if (curr->children[i]) {
ret += to_string(curr->children[i]->val);
q.push(curr->children[i]);
}
ret += " ";
}
ret += "#";
}
return ret;
}
Node *deserialize(string data) {
Node *ret;
if (data.size() == 0)
return NULL;
vector<vector<int>> v = createVector(data);
ret = new Node(v[0][0]);
queue<Node *> q;
q.push(ret);
int i = 1;
while (!q.empty() && i < v.size()) {
Node *curr = q.front();
q.pop();
for (int j = 0; j < v[i].size(); j++) {
int node = v[i][j];
Node *temp = new Node(node);
curr->children.push_back(temp);
q.push(temp);
}
i++;
}
return ret;
}
};
main() {
Codec ob;
Node n5(5), n6(6);
Node n3(3); n3.children.push_back(&n5); n3.children.push_back(&n6);
Node n2(2), n4(4);
Node n1(1); n1.children.push_back(&n3); n1.children.push_back(&n2);
n1.children.push_back(&n4);
cout << "Given Tree: " << n_ary_to_str(&n1) << endl;
string ser = ob.serialize(&n1);
cout << "Serialize: " << ser << endl;
Node *deser = ob.deserialize(ser);
cout << "Deserialized Tree: " << n_ary_to_str(deser);
} 입력
Node n5(5), n6(6); Node n3(3); n3.children.push_back(&n5); n3.children.push_back(&n6); Node n2(2), n4(4); Node n1(1); n1.children.push_back(&n3); n1.children.push_back(&n2); n1.children.push_back(&n4);
출력
Given Tree: 1[3[5, 6, ], 2, 4, ] Serialize: 1 #3 2 4 #5 6 ##### Deserialized Tree: 1[3[5, 6, ], 2, 4, ]