【详细解析】基础实验4-2.6 目录树 (30 分)
立志用最少的代碼做最高效的表達(dá)
在ZIP歸檔文件中,保留著所有壓縮文件和目錄的相對(duì)路徑和名稱。當(dāng)使用WinZIP等GUI軟件打開ZIP歸檔文件時(shí),可以從這些信息中重建目錄的樹狀結(jié)構(gòu)。請(qǐng)編寫程序?qū)崿F(xiàn)目錄的樹狀結(jié)構(gòu)的重建工作。
輸入格式:
輸入首先給出正整數(shù)N(≤10^4),表示ZIP歸檔文件中的文件和目錄的數(shù)量。隨后N行,每行有如下格式的文件或目錄的相對(duì)路徑和名稱(每行不超過260個(gè)字符):
路徑和名稱中的字符僅包括英文字母(區(qū)分大小寫);
符號(hào)“\”僅作為路徑分隔符出現(xiàn);
目錄以符號(hào)“\”結(jié)束;
不存在重復(fù)的輸入項(xiàng)目;
整個(gè)輸入大小不超過2MB。
輸出格式:
假設(shè)所有的路徑都相對(duì)于root目錄。從root目錄開始,在輸出時(shí)每個(gè)目錄首先輸出自己的名字,然后以字典序輸出所有子目錄,然后以字典序輸出所有文件。注意,在輸出時(shí),應(yīng)根據(jù)目錄的相對(duì)關(guān)系使用空格進(jìn)行縮進(jìn),每級(jí)目錄或文件比上一級(jí)多縮進(jìn)2個(gè)空格。
輸入樣例:
7
b
c
ab\cd
a\bc
ab\d
a\d\a
a\d\z
輸出樣例:
root
a
d
z
a
bc
ab
cd
d
c
b
解決思路
問題分析:
本題主要分為兩個(gè)子問題:一是根據(jù)輸入的信息建立樹,二是根據(jù)樹的結(jié)構(gòu)輸出文件目錄。
實(shí)現(xiàn)要點(diǎn):
建立樹時(shí),注意輸出順序,即同層目錄排在文件前,同類按字典序輸出。
所以在插入到每個(gè)節(jié)點(diǎn)時(shí),如果根節(jié)點(diǎn)左子樹為空,則直接插入,否則需要在其右子樹中循鏈掃描(它的兄弟節(jié)點(diǎn)) 并找到該節(jié)點(diǎn)插入的位置。
又注意到可能存在文件與目錄重名的情況,所以在存儲(chǔ)中,必須區(qū)別文件名或目錄名。
在輸出中,要注意不同層節(jié)點(diǎn)輸出不同的縮進(jìn)。以層數(shù)為參考即可。
具體實(shí)現(xiàn)邏輯:
插入規(guī)則:
首先判斷其是否有兒子節(jié)點(diǎn),如果無(wú),則直接建立節(jié)點(diǎn)插入即可。
反之,則在其兄弟鏈中查找位置(兒子節(jié)點(diǎn)的兄弟鏈)。
#include<iostream> #include<cstdio> using namespace std;struct TreeNode{string str;TreeNode* child; //左孩子TreeNode* sibling; //右兄弟int priority; //為0表示文件,為1表示目錄 }; typedef TreeNode* Position; typedef Position BinTree;//建樹,也可以說是初始化的過程 Position createNode(string s, int priority) {Position Node = new TreeNode;Node->str = s;Node->child = Node->sibling = NULL;Node->priority = priority;return Node; }//根據(jù)root的位置插入節(jié)點(diǎn) /* 插入節(jié)點(diǎn)前要想明白一個(gè)點(diǎn), 如果該文件或目錄還沒有創(chuàng)建,那么創(chuàng)建的一定是其兒子節(jié)點(diǎn)。 如果已經(jīng)創(chuàng)建完畢了,那么插入的位置一定在該節(jié)點(diǎn)的右子樹中查找。如 a/b c/d 1、從根節(jié)點(diǎn)插入a后,根節(jié)點(diǎn)左子樹為a,a的左子樹為b 2、從根節(jié)點(diǎn)插入c時(shí),發(fā)現(xiàn)其左子樹已經(jīng)被占據(jù),那么就遍歷其左子樹的右子樹 也就是根節(jié)點(diǎn)左子樹的兄弟節(jié)點(diǎn),直到找到合適的位置。遍歷d時(shí),也是同理。如果沒有被占據(jù),則直接創(chuàng)建兒子節(jié)點(diǎn)。 */ Position insert(BinTree root, string s, int priority) {if(root->child == NULL) { //如果沒有兒子,那么直接插入就可以了 root->child = createNode(s, priority); return root->child; //下一次插入從兒子開始 }//定義兒子節(jié)點(diǎn)和父親節(jié)點(diǎn)。 Position tmpNode = root->child, father = root;//如果有兒子,則循鏈找插入位置//若待插入節(jié)點(diǎn)優(yōu)先級(jí)更小或優(yōu)先級(jí)一致但字典序更大,則繼續(xù)循鏈//注意:邊界條件為!=NULL,也就是到了鏈末尾while(tmpNode != NULL && ((priority<tmpNode->priority) || (tmpNode->priority == priority && s>tmpNode->str))) {father = tmpNode;tmpNode = tmpNode->sibling;}//退出循環(huán)的三種情況://1、找到了鏈末尾 2、待插文件已存在 3、找到了應(yīng)該插入的位置//情況1if(tmpNode == NULL) {Position Node = createNode(s, priority);Node->sibling = father->sibling; //保存一下它的兄弟節(jié)點(diǎn) father->sibling = Node; return Node; } //情況2if(tmpNode->priority == priority && s==tmpNode->str)return tmpNode;//情況3else {Position Node = createNode(s, priority);if(father->str == root->str) { //如果該點(diǎn)為根節(jié)點(diǎn)下的第一個(gè)節(jié)點(diǎn) Node->sibling = father->child;father->child = Node;}else {Node->sibling = father->sibling;father->sibling = Node;}return Node; } } //layer是層數(shù),按層數(shù)輸出空格 void PreorderTraversal(BinTree BT, int layer) {int i;int childlayer, siblinglayer;if(BT) {for(i = 0; i < layer; i++) printf(" ");childlayer = layer+1;siblinglayer = layer;cout << BT->str << '\n';PreorderTraversal(BT->child, childlayer);PreorderTraversal(BT->sibling, siblinglayer);} }int main() {int N, i, bgn, end, j;string str;Position pos; //說是指針,其實(shí)就是節(jié)點(diǎn)BinTree root = createNode("root", 1);scanf("%d\n", &N);for(i = 0; i < N; i++) {getline(cin, str); pos = root; bgn = end = 0; //記錄文件首字符和最后一個(gè)字符的位置for(j = 0; j < str.length(); j++) {if(str[j] == '\\') {end = j;pos = insert(pos, str.substr(bgn, end-bgn), 1);bgn = end+1; //每次插入完成后更新起始字符位置 }}//讀完所有目錄后判斷字符串中是否還有文件 如果有,讀入文件 if(str[bgn] != '\0') {insert(pos, str.substr(bgn, str.length()-bgn), 0);} } PreorderTraversal(root, 0); //前序遍歷輸出 return 0; }
耗時(shí)
人生海海,潮起潮落,何須在乎潮落的時(shí)分,何須介意人生一時(shí)的崎嶇。???????——《人生海?!?/font>
總結(jié)
以上是生活随笔為你收集整理的【详细解析】基础实验4-2.6 目录树 (30 分)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【哈理工实验二】HTML+CSS3 旋转
- 下一篇: 【两种方法】基础实验4-2.7 修理牧场