E:文件結構“圖”
查看 提交 統計 提問
總時間限制: 1000ms 內存限制: 65536kB
描述
在計算機上看到文件系統的結構通常很有用。Microsoft Windows上面的"explorer"程序就是這樣的一個例子。但是在有圖形界面之前,沒有圖形化的表示方法的,那時候最好的方式是把目錄和文件的結構顯示成一個"圖"的樣子,而且使用縮排的形式來表示目錄的結構。比如:
ROOT
| dir1
| file1
| file2
| file3
| dir2
| dir3
| file1
file1
file2
這個圖說明:ROOT目錄包括三個子目錄和兩個文件。第一個子目錄包含3個文件,第二個子目錄是空的,第三個子目錄包含一個文件。
輸入
你的任務是寫一個程序讀取一些測試數據。每組測試數據表示一個計算機的文件結構。每組測試數據以’*‘結尾,而所有合理的輸入數據以’#‘結尾。一組測試數據包括一些文件和目錄的名字(雖然在輸入中我們沒有給出,但是我們總假設ROOT目錄是最外層的目錄)。在輸入中,以’]‘表示一個目錄的內容的結束。目錄名字的第一個字母是’d’,文件名字的第一個字母是’f’。文件名可能有擴展名也可能沒有(比如fmyfile.dat和fmyfile)。文件和目錄的名字中都不包括空格,長度都不超過30。一個目錄下的子目錄個數和文件個數之和不超過30。
輸出
在顯示一個目錄中內容的時候,先顯示其中的子目錄(如果有的話),然後再顯示文件(如果有的話)。文件要求按照名字的字母表的順序顯示(目錄不用按照名字的字母表順序顯示,只需要按照目錄出現的先後顯示)。對每一組測試數據,我們要先輸出"DATA SET x:",這裏x是測試數據的編號(從1開始)。在兩組測試數據之間要輸出一個空行來隔開。
你需要注意的是,我們使用一個’|'和5個空格來表示出縮排的層次。
樣例輸入
file1
file2
dir3
dir2
file1
file2
]
]
file4
dir1
]
file3
*
file2
file1
*
樣例輸出
DATA SET 1:
ROOT
| dir3
| | dir2
| | file1
| | file2
| dir1
file1
file2
file3
file4
DATA SET 2:
ROOT
file1
file2
提示
一個目錄和它的子目錄處於不同的層次
一個目錄和它的裏面的文件處於同一層次
半截的失敗代碼
想把在*號之前的全輸入後再進行輸出,但是越寫繁瑣,最終放棄,估計調完也該130多行了。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int k=1;
void root(int i,int t)
{
if(p[i][0]=='d')
{
t++;
pout(i,t);
root(i+1,t);
}
if(p[i][0]=='f')
{
ppout(i,t);
root(i+1,t);
}
}
void ppout(int i,int t)
{
if(p[i][0]=='f')
{
ccp[k++]=p[i];
ppout(i+1,t);
}
else
{
if(k>1)
{
sort(ccp+1,ccp+k);
for(int ii=1;ii<=k-1;ii++)
{
for(int j=1;j<=t;j++)
{
cout<<"| ";
}
cout<<ccp[ii]<<endl;
}
return ;
}
else
{
for(int j=1;j<=t;j++)
{
cout<<"| ";
}
cout<<ccp[1]<<endl;
}
}
}
void pout(int i,int t)
{
for(int j=1;j<=t;j++)
{
cout<<"| ";
}
cout<<p[i]<<endl;
}
int main()
{
string p[35];
string cp[35];
while(1)
{
int i=1;
int l=1;
int j=1;
while(1)
{
cin>>p[i];
if(p[i][0]=='f') cp[l++]=p[i];
if(p[i]=="*"||p[i]=="#") break;
i++;
}
if(p[i]=="#") break;
if(l>1) sort(cp+1,cp+l);
cout<<"DATA SET "<<j<<":"<<endl;
cout<<"ROOT"<<endl;
int ii=1;
while(1)
{
if(p[ii][0]=='d')
{
root(ii,0);
}
ii++;
if(p[ii][0]=='*') break;
}
for(int jj=1;jj<=i;jj++)
{
cout<<cp[jj]<<endl;
}
}
return 0;
}
第二次寫的時候想用set,但是如果全把*號前的全輸入後再輸出也很難完成,
注意題目中的要求,最後一次輸出file時並未要求要把出現的file全部在最後一次輸出。
失敗代碼
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
string p[35];
void dout(int i,int t)
{
for(int j=1;j<=t;j++)
{
cout<<"| ";
}
cout<<p[i]<<endl;
}
void fout(int t,set<string>fp)
{
for(set<string>::iterator it=fp.begin();it!=fp.end();it++)
{
for(int j=1;j<=t;j++)
{
cout<<"| ";
}
cout<<*it<<endl;
}
}
void zout(set<string>fp)
{
for(set<string>::iterator it=fp.begin();it!=fp.end();it++)
{
cout<<*it<<endl;
}
}
void root(int i,int t)
{
set<string>fp;
while(1)
{
if(p[i][0]=='f')
{
fp.insert(p[i]);
}
else if(p[i][0]=='d')
{
t++;
dout(i,t);
root(i+1,t);
}
else if(p[i]=="]")
{
fout(t,fp);
t--;
return ;
}
if(p[i]=="*")
{
zout(fp);
return ;
}
i++;
}
}
int main()
{
int op=0;
while(1)
{
int i=1;
while(1)
{
cin>>p[i];
if(p[i]=="*"||p[i]=="#"){op++; break;}
i++;
}
if(p[i]=="#") break;
cout<<"DATA SET "<<op<<":"<<endl;
cout<<"ROOT"<<endl;
root(1,0);
}
return 0;
}
如果邊輸入邊輸出的話,事情就變得比較簡單了
而且題目中的條件是輸入的file一定是不重複的,因此
代碼中的set可以改成優先隊列。
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int i=0;
int num=1;
int jud=1;
int op=1;
void pout()
{
if(op) {cout<<"DATE SET "<<num<<":"<<endl<<"ROOT"<<endl;op=0;}
}
void root()
{
string p;
set<string>fp;
while(cin>>p)
{
if(p[0]=='f')
{
fp.insert(p);
pout();
}
else if(p[0]=='d')
{
pout();
i++;
for(int j=1;j<=i;j++)
{
cout<<"| ";
}
cout<<p<<endl;
root();
}
else if(p=="]")
{
for( set<string>::iterator it=fp.begin();it!=fp.end();it++)
{
for(int j=1;j<=i;j++)
{
cout<<"| ";
}
cout<<*it<<endl;
}
i--;
return ;
}
else if(p=="*")
{
for(set<string>::iterator it=fp.begin();it!=fp.end();it++)
{
cout<<*it<<endl;
}
i=0;
num++;
op=1;
return ;
}
else if(p=="#")
{
jud=0;
return ;
}
}
}
int main()
{
while(jud)
{
if(jud==0) break;
// cout<<"DATE SET "<<num<<":"<<endl;
// cout<<"ROOT"<<endl;
root();
}
return 0;
}