题解 | 路径打印

路径打印

https://www.nowcoder.com/practice/64b472c9bed247b586859978d13145ad

法一

先对字符串排序,相同前缀的路径下标是连续的

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 15;
string s[N];

// "a\b\c"  -->  ["a", "b", "c"]
vector<string> split(string &s) {
	vector<string> res;
	
	string temp = "";
	for (int i = 0; i < s.size(); i++) {
		if (s[i] == '\\') {
			if (temp.size()) {
				res.push_back(temp);   // 遇到 '\' 当前目录加入数组
				temp = "";
			}
		}
		else {
			temp += s[i];              // 没遇到 '\' 记录当前目录名称
		}
	}

	if (temp.size())
		res.push_back(temp);           // 最后一个目录要加入数组

	return res;
}


int main() {
	int n;

	vector<string> cur, pre;

	while (cin >> n, n != 0) {
		pre.clear();

		for (int i = 0; i < n; i++) cin >> s[i];

		// 排序后,相同前缀的目录串下标一定连续
		sort(s, s + n);

		for (int i = 0; i < n; i++) {
			cur = split(s[i]);

			// 相同的前缀不输出
			int st = 0;
			while (st < pre.size() && st < cur.size() && pre[st] == cur[st]) 
				st++;

			while (st < cur.size()) {
				cout << string(st * 2, ' ');    // 输出多个空格
				cout << cur[st] << endl;
				st++;
			}
			pre = cur;
		}
		cout << endl;
	}
}

法二

用数组形式的 trie树 保存 & 遍历

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

const int N = 15, M = N * 50;
string s[N];

int idx;
map<string, int> son[M];   // trie树,且每个结点的分支为字典序

// trie 树插入结点
void insert(vector<string> paths) {
	int p = 0;

	for (auto& path : paths) {
		if (!son[p].count(path))
			son[p][path] = ++idx;
		p = son[p][path];
	}
}


// 先序遍历trie树并打印
void dfs(int u, int depth) {
	for (auto &p : son[u]) {
		// 输出          空格         +     目录  +   换行
		cout << string(depth * 2, ' ') << p.first << endl;  // 先访问根
		dfs(p.second, depth + 1);                           // 再访问其余分支
	}
}


// "a\b\c"  -->  ["a", "b", "c"]
vector<string> split(string& s) {
	vector<string> res;

	string temp = "";
	for (int i = 0; i < s.size(); i++) {
		if (s[i] == '\\') {
			if (temp.size()) {
				res.push_back(temp);   // 遇到 '\' 当前目录加入数组
				temp = "";
			}
		}
		else {
			temp += s[i];              // 没遇到 '\' 记录当前目录名称
		}
	}

	if (temp.size())
		res.push_back(temp);           // 最后一个目录要加入数组

	return res;
}



int main() {
	int n;
	while (cin >> n, n != 0) {

		idx = 0;
		for (int i = 0; i < M; i++)
			son[i].clear();            // 清理trie树

		while (n--) {
			string s;
			cin >> s;

			auto path = split(s);      // 拆成目录数组
			insert(path);              // 插入trie树
		}

		dfs(0, 0);                     // 遍历trie树并输出
		cout << endl;
	}
}

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务