文件結構圖

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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章