阿里云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;
}

浙公网安备 33010602011771号