浙大PAT 4-08. 目录树 (解题思路)

4-08. 目录树

时间限制
400 ms
内存限制
32000 kB
代码长度限制
8000 B
判题程序
Standard

在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。

输入格式说明:

输入首先给出正整数N(<=104),表示ZIP归档文件中的文件和目录的数量。随后N行,每行有如下格式的文件或目录的相对路径和名称(每行不超过260个字符):

1) 路径和名称中的字符仅包括英文字母(区分大小写);
2) 符号“\”仅作为路径分隔符出现;
3) 目录以符号“\”结束;
4) 不存在重复的输入项目;
5) 整个输入大小不超过2MB。

输出格式说明:

假设所有的路径都相对于root目录。从root目录开始,在输出时每个目录首先输出自己的名字,然后以字典序输出所有子目录,然后以字典序输出所有文件。注意,在输出时,应根据目录的相对关系使用空格进行缩进,每级目录或文件比上一级多缩进2个空格。

样例输入与输出:

序号输入输出
1
7
b
c\
ab\cd
a\bc
ab\d
a\d\a
a\d\z\
root
  a
    d
      z
      a
    bc
  ab
    cd
    d
  c
  b
2
1
z\
root
  z


//写这题的时候要注意目录和文件的名字输出时是有优先级的,目录先输出!所以我用了比较笨的方法,多定义了一个bool mulu;

#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
using namespace std;


typedef struct Node
{
	string name;
	bool mulu;
	deque<struct Node*> next;
	Node(string s, bool m)
	{
		name = s;
		mulu = m;
	}
}Node;

bool cmp(Node* t1, Node* t2)
{
	if((t1->mulu == true && t2->mulu == true) ||
	   (t1->mulu == false && t2->mulu == false))
	{
		if((t1->name).compare(t2->name) < 0)
			return true;
		else
			return false;
	}
	else
		if(t1->mulu == true)
			return true;
		else
			return false;
}

void Insert(Node* &root, string s)
{
	if(s == "")
		return;
	int index = -1;
	if((index = s.find_first_of('\\')) != string::npos)
	{
		string name = s.substr(0, index);
		string ts = s.substr(index+1, s.length());
		bool flag = true;
		int j;
		for(int i = 0; i < (root->next).size(); ++i)
			if((root->next)[i]->name == name)
			{
				flag = false;
				j = i;
				break;
			}

		if(flag)
		{
			Node* p = new Node(name, true);
			(root->next).push_back(p);
			Insert((root->next).back(), ts);

		}
		else
			Insert((root->next)[j], ts);
	}
	else
	{
		bool flag = true;
		for(int i = 0; i < (root->next).size(); ++i)
		{
			if((root->next)[i]->name == s)
				flag = false;
		}
		if(flag)
		{
			Node* p = new Node(s, false);
			(root->next).push_back(p);
		}
	}
}


void Print(Node* &root, int ceng)
{
	if((root->next).size() == 0)
		return;
	for(int i = 0; i < (root->next).size(); ++i)
	{
		sort((root->next).begin(), (root->next).end(), cmp);
		for(int j = 0; j < ceng; ++j)
			cout<<"  ";
		cout<<(root->next)[i]->name<<endl;
		Print((root->next)[i], ceng+1);
	}
}

int main()
{
	int n;
	cin>>n;
	Node* root = new Node("root", true);
	root->name = "root";
	while(n--)
	{
		string s;
		cin>>s;
		Insert(root, s);
	}
	cout<<"root"<<endl;
	Print(root, 1);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值