咕咕東的雪梨電腦的作業系統在上個月受到宇宙射線的影響,時不時發生故障,他受不了了,想要寫乙個高效易用零bug的作業系統 —— 這工程量太大了,所以他定了乙個小目標,從實現乙個目錄管理器開始。前些日子,東東的電腦終於因為過度收到宇宙射線的影響而宕機,無法寫**。他的好友tt正忙著在b站看貓片,另一位好友瑞神正忙著打守望先鋒。現在只有你能幫助東東!
初始時,咕咕東的硬碟是空的,命令列的當前目錄為根目錄 root。
目錄管理器可以理解為要維護一棵有根樹結構,每個目錄的兒子必須保持字典序。
現在咕咕東可以在命令列下執行以下**中描述的命令:
命令 型別 實現 說明
mkdir s 操作 在當前目錄下建立乙個子目錄 s,s 是乙個字串 建立成功輸出 「ok」;若當前目錄下已有該子目錄則輸出 「err」
rm s 操作 在當前目錄下刪除子目錄 s,s 是乙個字串 刪除成功輸出 「ok」;若當前目錄下該子目錄不存在則輸出 「err」
cd s 操作 進入乙個子目錄 s,s 是乙個字串(執行後,當前目錄可能會改變) 進入成功輸出 「ok」;若當前目錄下該子目錄不存在則輸出 「err」
特殊地,若 s 等於 「…」 則表示返回上級目錄,同理,返回成功輸出 「ok」,返回失敗(當前目錄已是根目錄沒有上級目錄)則輸出 「err」
sz 詢問 輸出當前目錄的大小 也即輸出 1+當前目錄的子目錄數
ls 詢問 輸出多行表示當前目錄的 「直接子目錄」 名 若沒有子目錄,則輸出 「empty」;若子目錄數屬於 [1,10] 則全部輸出;若子目錄數大於 10,則輸出前 5 個,再輸出一行 「…」,輸出後 5 個。
tree 詢問 輸出多行表示以當前目錄為根的子樹的前序遍歷結果 若沒有後代目錄,則輸出 「empty」;若後代目錄數+1(當前目錄)屬於 [1,10] 則全部輸出;若後代目錄數+1(當前目錄)大於 10,則輸出前 5 個,再輸出一行 「…」,輸出後 5 個。若目錄結構如上圖,當前目錄為 「root」 執行結果如下root dira a b c dirb x dirc y(之間有回車)。
undo 特殊 撤銷操作 撤銷最近乙個 「成功執行」 的操作(即mkdir或rm或cd)的影響,撤銷成功輸出 「ok」 失敗或者沒有操作用於撤銷則輸出 「err」。
基本思路都按照課件的思路來寫的,所以就寫一寫自己思考的東西。
mkdir:如果不存在節點,要在node[now].mp裡新增兒子關係,然後從now向根節點更新子樹節點數目sz。接下來要在node[index]裡建立新節點,節點所有資訊都進行初始化,然後將操作記錄在vector v中,以便undo時使用。
rm:只用刪除邊關係,不用刪除節點,以便於undo時恢復邊和節點。
undo:首先是結構point:string name,int now,int next。name為操作名稱,now為當前目錄,next為要新增/刪除/移到的目錄位置。用vector v來記錄操作序列。當undo時就取出v尾部的節點,根據節點資訊來進行undo操作。
tree:需要用到遍歷子樹pushdown操作。而pushdown裡要有求子樹所有節點alltrack(節點個數<=10),求前五個節點pretrack和後五個節點bcktrack。alltrack只需要前序遍歷子樹,將節點放在vector pre中即可;pretrack用num來記錄還要選幾個節點,遞迴遍歷時若num為0則return;bcktrack同樣用num來記錄,不過遍歷是先進入到最右兒子直到到達葉子,然後再取該節點。
一道非常複雜的模擬題,如果沒有上課時所講的思路,估計幾天也a不了,因為會各種超時。以後做題時要先分析複雜度,再根據複雜度來選擇資料結構和演算法,以免寫完**之後才發現t要進行重構。
同時還發現了自己迭代器的使用不夠熟練,begin~end是前閉後開,反向遍歷時第乙個數是it=end();it–;寫的時候寫錯了,re除錯了好久。
#include
#include
#include
#include
using
namespace std;
struct directory
;directory node[
200000];
int now,index;
//當前節點與最新節點
struct point //用於undo儲存資訊
;vector v;
void
update
(int id,
int num)
//將變化資料向上傳導
}void
mkdir
(string &s)
//在當前目錄下建立乙個子目錄s
}void
rm(string &s)
//在當前目錄下刪除子目錄s
else cout<<
"err"
<}void
cd(string &s)
//進入子目錄s
}else
//進入子目錄s
else cout<<
"err"
)//輸出當前目錄的大小
voidls(
)//輸出當前目錄的直接子目錄名
else
//輸出前五個和後五個
cout<<
"..."
/後五個
it=node[now]
.mp.
end();
for(
int i=
1; i<=
5; i++
) it--
;for
(int i=
1; i<=
5; i++)}
}void
alltrack
(int id,vector
&pre)
//遍歷id子樹,求出全部(小於10個)
void
pretrack
(int id,vector
&pre,
int&num)
//遍歷id子樹,求出前五個
}void
bcktrack
(int id,vector
&bck,
int&num)
//遍歷id子樹,求出後五個
bck.
push_back
(node[id]
.name)
; num--;}
void
pushdown
(int id)
//遍歷id子樹
node[id]
.tag=1;
}void
tree()
//輸出以當前目錄為根的子樹的前序遍歷結果
else
}void
undo()
//撤銷最近乙個成功執行的mkdir或rm或cd
else
if(p.name==
"rm"
)//要新增
else
//要返回
now=p.now;}}
intmain()
else
if(op==
"rm"
)else
if(op==
"cd"
)else
if(op==
"sz")sz
();else
if(op==
"ls")ls
();else
if(op==
"tree"
)tree()
;else
if(op==
"undo"
)undo()
;}}}
week9 作業A 咕咕東的目錄管理器
咕咕東的雪梨電腦的作業系統在上個月受到宇宙射線的影響,時不時發生故障,他受不了了,想要寫乙個高效易用零bug的作業系統 這工程量太大了,所以他定了乙個小目標,從實現乙個目錄管理器開始。前些日子,東東的電腦終於因為過度收到宇宙射線的影響而宕機,無法寫 他的好友tt正忙著在b站看貓片,另一位好友瑞神正忙...
WEEK9 A 咕咕東的目錄管理器
咕咕東的雪梨電腦的作業系統在上個月受到宇宙射線的影響,時不時發生故障,他受不了了,想要寫乙個高效易用零bug的作業系統 這工程量太大了,所以他定了乙個小目標,從實現乙個目錄管理器開始。前些日子,東東的電腦終於因為過度收到宇宙射線的影響而宕機,無法寫 他的好友tt正忙著在b站看貓片,另一位好友瑞神正忙...
程式設計Week9 A 咕咕東的目錄管理器
每組測試資料的輸出結果間需要輸出一行空行。注意大小寫敏感。以封裝的思想來實現每個小功能,由於有undo的操作,因此對於mkdir rm cd三種操作需要記錄每一次操作的過程 建立乙個目錄相關的結構體,其中包括檔名,當前檔案的子目錄的map,父節點以及當前檔案下子樹 目錄 的規模,當前目錄下先序遍歷 ...