Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

จัดทำซีเรียลและถอดซีเรียลต้นไม้ N-ary ใน C++


สมมติว่าเรามีต้นไม้ N-ary และเราต้องจัดทำซีเรียล (serialize) และถอดซีเรียล (deserialize) ต้นไม้นั้น ตามที่รู้จักว่าการซีเรียลคือการแปลงโครงสร้างข้อมูลหรือวัตถุเป็นลำดับบิต เพื่อเก็บในไฟล์หรือบัฟเฟอร์หน่วยความจำ และสามารถสร้างคืนได้ภายหลังในสภาพแวดล้อมเดียวกันหรือต่างกัน

ที่นี่เราต้องออกแบบอัลกอริทึมเพื่อซีเรียลและถอดซีเรียลต้นไม้ N-ary ต้นไม้ N-ary คือต้นไม้ที่มีราก ซึ่งแต่ละโหนดมีลูกไม่เกิน N โหนด

เช่น ถ้าอินพุตเป็นรูปภาพดังนี้:

จัดทำซีเรียลและถอดซีเรียลต้นไม้ N-ary ใน C++

ผลลัพธ์จะเป็น Serialize: 1 #3 2 4 #5 6 ##### และ Deserialized Tree: 1[3[5, 6, ], 2, 4, ]

ในการแก้ปัญหานี้ เราจะทำตามขั้นตอนต่อไปนี้:

  • กำหนดฟังก์ชัน createVector() รับ s: แยกสตริงเป็นเวกเตอร์ 2 มิติของจำนวนเต็ม โดยใช้ '#' และช่องว่าวเป็นตัวคั่น
  • กำหนดฟังก์ชัน serialize() รับ root: ใช้ BFS (Queue) เขียนค่าราก แล้วตามด้วยลูกของแต่ละโหนด คั่นระดับด้วย '#'
  • กำหนดฟังก์ชัน deserialize() รับ data: ใช้ createVector() ได้โครงสร้างระดับ แล้วสร้างต้นไม้ทีละระดับด้วย Queue

ตัวอย่าง

ลองดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น:

#include <bits/stdc++.h>
using namespace std;
class Node {
public:
    int val;
    vector children;
    Node() {}
    Node(int _val) { val = _val; }
    Node(int _val, vector _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> createVector(string s) {
        vector> ret;
        vector 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 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> v = createVector(data);
        ret = new Node(v[0][0]);
        queue 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, ]