題目來源:http://noi.openjudge.cn/ch0202/1777/ 1777:檔案結構“圖”
總時間限制: 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 SETx:",這裡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
提示
一個目錄和它的子目錄處於不同的層次
一個目錄和它的裡面的檔案處於同一層次
-----------------------------------------------------
解題思路
用棧來表示目錄的深入與退出
再次提醒:C++裡要用棧的話vector類比stack類好用,用vector類就行了
-----------------------------------------------------
代碼
#include<fstream>#include<iostream>#include<algorithm>#include<vector>#include<string>using namespace std;int main(){ #ifndef ONLINE_JUDGEifstream fin("xly2016D.txt");if (!fin){exit(1);} string buf;vector<string>::iterator it;vector< vector<string> > fstack;// 用棧刻畫目錄的加深和退出vector<string> fbuf;// 檔案名稱臨時儲存數組 int n_dataset = 1; int n_tab = 0; int i = 0, j = 0; fin >> buf; while (buf != "#") { if (fstack.empty() && fbuf.empty())// 如果棧和檔案清單均為空白,說明開了一個新的資料集{cout << "DATA SET " << n_dataset << ":" << endl;cout <<"ROOT" << endl;}if (buf == ""){continue;}if (buf.at(0)=='d') { n_tab++;if (n_tab>0){for (i=0; i<n_tab; i++){buf = "| " + buf;}} cout << buf << endl;// 直接輸出目錄名fstack.push_back(fbuf);// 老的檔案清單儲存入棧fbuf.clear();// 進到新的一層目錄,清空檔案名稱列表以備記錄新目錄下的檔案 } else if (buf.at(0)=='f') { if (n_tab>0){for (i=0; i<n_tab; i++){buf = "| " + buf;}} fbuf.push_back(buf);// 將檔案名稱添到檔案名稱列表 } else if (buf=="]") { sort(fbuf.begin(), fbuf.end());// 將檔案名稱按字典順序排序for (it=fbuf.begin(); it!=fbuf.end(); it++){cout << (*it) << endl;// 按字典順序輸出該級目錄下所有檔案}fbuf = fstack.back();// 回到上層目錄的檔案名稱列表fstack.pop_back();// 彈出該檔案清單n_tab--; } else if (buf=="*") { sort(fbuf.begin(), fbuf.end());// 將檔案名稱按字典順序排序for (it=fbuf.begin(); it!=fbuf.end(); it++){cout << (*it) << endl;// 按字典順序輸出該級目錄下所有檔案}fbuf.clear();// 清空檔案清單fstack.clear();// 清空檔案清單棧cout << endl; n_dataset++; n_tab = 0; }fin >> buf; } fin.close();return 0; #endif // LOCAL FILE#ifdef ONLINE_JUDGEstring buf;vector<string>::iterator it;vector< vector<string> > fstack;// 用棧刻畫目錄的加深和退出vector<string> fbuf;// 檔案名稱臨時儲存數組 int n_dataset = 1; int n_tab = 0; int i = 0, j = 0; cin >> buf; while (buf != "#") { if (fstack.empty() && fbuf.empty())// 如果棧和檔案清單均為空白,說明開了一個新的資料集{cout << "DATA SET " << n_dataset << ":" << endl;cout <<"ROOT" << endl;}if (buf == ""){continue;}if (buf.at(0)=='d') { n_tab++;if (n_tab>0){for (i=0; i<n_tab; i++){buf = "| " + buf;}} cout << buf << endl;// 直接輸出目錄名fstack.push_back(fbuf);// 老的檔案清單儲存入棧fbuf.clear();// 進到新的一層目錄,清空檔案名稱列表以備記錄新目錄下的檔案 } else if (buf.at(0)=='f') { if (n_tab>0){for (i=0; i<n_tab; i++){buf = "| " + buf;}} fbuf.push_back(buf);// 將檔案名稱添到檔案名稱列表 } else if (buf=="]") { sort(fbuf.begin(), fbuf.end());// 將檔案名稱按字典順序排序for (it=fbuf.begin(); it!=fbuf.end(); it++){cout << (*it) << endl;// 按字典順序輸出該級目錄下所有檔案}fbuf = fstack.back();// 回到上層目錄的檔案名稱列表fstack.pop_back();// 彈出該檔案清單n_tab--; } else if (buf=="*") { sort(fbuf.begin(), fbuf.end());// 將檔案名稱按字典順序排序for (it=fbuf.begin(); it!=fbuf.end(); it++){cout << (*it) << endl;// 按字典順序輸出該級目錄下所有檔案}fbuf.clear();// 清空檔案清單fstack.clear();// 清空檔案清單棧cout << endl; n_dataset++; n_tab = 0; }cin >> buf; }return 0;#endif}