题目
答案
#include<iostream>
#include<algorithm>//使用sort函数
#include<cstring>//使用字符串相关函数
using namespace std;
//定义常量
const int N = 500;
//创建结构体
typedef struct node{
char name[N];//名字
int dir;//是否为目录,1是,0不是
int num;//拥有的目录和文件总和
struct node *next[N];//下一级
}Node,*Tree;
//自定义排序方式
bool cmp(Tree a,Tree b)
{
if(a->dir!=b->dir) return a->dir>b->dir;//目录优先,文件靠后
else return strcmp(a->name,b->name)<0; //级别相同,则按字典序排列
}
//类前序遍历
void pre_order(Tree root,int cnt)
{
for(int i=0;i<cnt*2;i++)//循环输出空格
cout<<" ";
cout<<root->name<<endl;
sort(root->next,root->next+root->num,cmp);//排序
for(int i=0;i<root->num;i++)//向下一级进发
pre_order(root->next[i],cnt+1);
}
//主函数
int main()
{
//定义相关变量
int i,j,n,size;
//root初始化
Tree root = new Node;
strcpy(root->name,"root");
root->dir=1;
root->num=0;
for(i=0;i<N;i++)
root->next[i]=NULL;
//输入总数n
cin>>n;
while(n--)
{
//从根节点开始
Tree p=root;
//定义两个字符数组
char str[N],s[N];
//输入字符串
cin>>str;
int k=0,len=strlen(str);
for(i=0;i<len;i++)//遍历字符串
{
if(str[i]!='\\') s[k++]=str[i];// '\' 要用 '\\' 来表示
else
{
s[k]='\0';//加上结束符
size=p->num;
for(j=0;j<size;j++)//遍历寻找该目录是否已经存在
if(strcmp(p->next[j]->name,s)==0)
{
p=p->next[j];
break;
}
if(j==size)//如果不存在
{
size=p->num;
p->next[size]=new Node;//创建新节点
strcpy(p->next[size]->name,s);
p->next[size]->dir=1;
p->next[size]->num=0;
p->num+=1;
p=p->next[size];
}
k=0;//k还原为0
}
}
if(str[len-1]!='\\')//如果最后一个是文件
{
s[k]='\0';
size=p->num;
p->next[size]=new Node;//创建新节点
strcpy(p->next[size]->name,s);
p->next[size]->dir=0;
p->next[size]->num=0;
p->num++;
}
}
pre_order(root,0);//遍历打印结果
}
总结
本题的思路是采用字典树解题,我个人对于字典树的理解就是在链表的基础上,将next扩展为数组,以实现1对多的目的
本题我参考了这篇文章——目录树 PTA,注释方面进行了个性化的修改