【POJ1760】Disk Tree

显然本题是要将文件组织成一棵树,直观的想法就是用相应的文件名(字符串)作为结点的data域,同时给结点编号,形成一个一一映射。

如果用指针和动态建树的方法,由于我们并不确定一个文件名下到底有多少子文件(子树),所以就难以确定子结点的个数,因此考虑用类似字典树的方式建树。不同的是,字典树的每个结点是一个字符,

而本题的每个结点是一个字符串。

如何将字符串和编号联系起来?显然要用map。第一个问题就解决了。

那么如何组织成一棵树呢?上面说了用类似建trie的方式编号,具体的实现方式自然就是用map数组map<string,int>M[maxn]。每一个M[i]都是一个map,而M[i]可以组织起根节点编号为i的所有子树。

 1 #include<iostream>
 2 #include<string>
 3 #include<map>
 4 using namespace std;
 5 string t,s;
 6 map<string,int>M[20001];
 7 int tot,n,p,pos;
 8 void pre(int m,int s){ //m:当前编号,s:前导空格 
 9     map<string,int>::iterator it;
10     for(it=M[m].begin();it!=M[m].end();++it){
11         for(int i=0;i<s;i++) cout<<' ';
12         cout<<it->first<<endl;
13         pre(it->second,s+1);
14     }
15 }
16 int main()
17 {
18     cin>>n;
19     while(n--){
20         int now=0;   //当前所在树的结点编号 
21         cin>>t;
22         pos=p=0;     //将'\'作为分隔符依次抽取子串插入树中 
23         while((p=t.find('\\',p))!=-1){
24             s=t.substr(pos,p-pos);
25             if(!M[now].count(s)) M[now][s]=++tot;
26             now=M[now][s];
27             pos=++p;
28         }
29         s=t.substr(pos);
30         if(!M[now].count(s)) M[now][s]=++tot; //处理最后一个文件名 
31     }
32     pre(0,0);
33 }

如果用it指向M[i]的某个元素(也就是根节点编号为i的某个儿子),it->first就是文件名,it->second就是该儿子的编号,从而可以递归地实现输出。

由于map的插入本身是有序的,故要实现字典序输出,只需要前序遍历即可。

posted @ 2017-11-01 16:05  sulley  阅读(343)  评论(0编辑  收藏  举报