阿里云2023年暑期实习测开手撕题:找文件和目录的共同父目录

题目:目录里面会包含文件/目录,目录会有递归的结构存在,明确定义: 目录/文件名称都是唯一的给两个结点,文件或者目录的名称,找到这个文件和目录的最低层次的公共目录。

参考代码如下,有点类似于leetcode中的找二叉树共同祖先,把目录树当成多叉树处理即可:

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>

struct Node{
    Node(){name = "";}
    Node(std::string name_) {
        name = name_;
    }
    std::string name;
    std::vector<Node*> children;
};

// 将字符串转为目录树(多叉树
Node* toTree(std::string addr) {
    Node *root = new Node();
    int beg = -1, end = -1;
    std::stack<Node*> s;
    s.push(root);
    for (int i = 0; i < addr.size(); i++) {
        if (addr[i] == '(') {
            // 截取文件名
            std::string name = addr.substr(beg, end - beg + 1);
            // '('左侧的文件名一定是目录的
            Node *file = new Node(name);
            Node *dir = s.top();
            dir->children.push_back(file);
            s.push(file);// 接下来读取的文件必定以此为目录
            beg = -1;
        } else if (addr[i] == ',') {
            // 接下来取出的文件名属于一个普通文件,其父目录是stack栈顶的目录
            // 取出栈顶目录后不排除后面还有文件也属于这个目录,因此不能直接弹出栈顶元素
            if (addr[i - 1] == ')') continue;
            Node *dir = s.top();
            std::string name = addr.substr(beg, end - beg + 1);
            Node *file = new Node(name);
            dir->children.push_back(file);
            beg = -1;
        } else if (addr[i] == ')') {
            if (addr[i - 1] == ')') {
                s.pop();
                continue;
            }
            Node *dir = s.top();
            std::string name = addr.substr(beg, end - beg + 1);
            Node *file = new Node(name);
            dir->children.push_back(file);
            beg = -1;
            s.pop();
        } else {
            if (beg == -1)  beg = i;
            end = i;
        }
    }
    return root;
}

Node* findDir(std::string fileA, std::string fileB, Node *root) {
    if (root == NULL) return NULL;
    if (root->name == fileA || root->name == fileB) return root;
    int size = root->children.size();
    std::vector<Node*> v(size, NULL);
    for (int i = 0; i < size; i++) {
        v[i] = findDir(fileA, fileB, root->children[i]);
    }
    Node *left = NULL, *right = NULL;
    for (int i = 0; i < size; i++) {
        if (v[i] != NULL && left != NULL) right = v[i];
        if (v[i] != NULL && left == NULL) left = v[i];
    }
    if (left != NULL && right != NULL) return root;
    if (left != NULL) return left;
    return right;
}

int main() {
    std::string str = "a(b(e,f(g,h)),c,d(i,j))";
    Node *root = toTree(str);
    // 按照层级顺序打印目录树
    std::queue<Node*> q;
    q.push(root);
    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            Node *node = q.front();
            q.pop();
            std::cout<<node->name<<' ';
            int vsize = node->children.size();
            for (int j = 0; j < vsize; j++) {
                q.push(node->children[j]);
            }
        }
        std::cout<<std::endl;
    }
    Node *par = findDir("e", "g", root->children[0]);
    std::cout<<par->name<<std::endl;
    return 0;
}

  

 

posted @ 2023-11-01 20:29  宇宙之母蔡依林  阅读(14)  评论(0)    收藏  举报