problem
我认为看这个英文版的很舒服(当然看中文也很爽:
题目
test data
样例输入:
1
22
MKDIR dira
CD dirb
CD dira
MKDIR a
MKDIR b
MKDIR c
CD ..
MKDIR dirb
CD dirb
MKDIR x
CD ..
MKDIR dirc
CD dirc
MKDIR y
CD ..
SZ
LS
TREE
RM dira
TREE
UNDO
TREE
样例输出
OK
ERR
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
9
dira
dirb
dirc
root
dira
a
b
c
dirb
x
dirc
y
OK
root
dirb
x
dirc
y
OK
root
dira
a
b
c
dirb
x
dirc
y
简单解释
解释:其实TA已经在课堂上解释了一遍,还敲了一遍代码(写了一遍代码
所以,,,,,,,,,,
首先看到这道复杂的题,要有一个代码框架,不要直接把它看成一个大问题,事实就是你很难直接解决一个大问题,但是你解决一个小问题会非常容易。所以有句话叫做:“大事化小,小事化了。”
我们要对一个目录进行操作,建立,删除,查询,撤销操作等等,所以建立一个字符串数组,存操作的名称,建立一个结构体,或者声明一个类,将操作包含进去,然后分别实现每一个函数。莫非这就是对函数进行封装。
我理解的封装就是class{public: private};
Codes
#include<iostream>
#include<map>
#include<cstring>
#include<vector>
using namespace std;
string str;
struct Dr{
string name;//目录名
map<string,Dr*> kids;//子目录
Dr *par;//父目录
int tsize;//目录个数
bool update;//是否更新
vector<string> desc;//存储遍历的后代
Dr(string nam,Dr *pa){
this->name=nam;
this->par=pa;
this->tsize=1;
}
public:
Dr* getkid(string st){
auto it=kids.find(st);
if(it==kids.end()) return NULL;
else
return it->second;
}
void maintain(int x){
update=true;
tsize+=x;
if(par!=NULL)
par->maintain(x);
}
bool addkid(Dr* sr){
if(kids.find(sr->name) != kids.end())
return false;
kids[sr->name]=sr;
maintain(+sr->tsize);
return true;
}
Dr* mkdir(string st){
if(kids.find(st)!=kids.end())
return NULL;
Dr* d=new Dr(st,this);
kids[st]=d;
maintain(1);
return d;
}
Dr* rm(string st){
auto it=kids.find(st);
if(it==kids.end())
return NULL;
maintain(-1*it->second->tsize);
Dr *tmp=it->second;
kids.erase(it);
return tmp;
}
Dr* cd(string st){
if(st=="..")//判断是否返回上一步
return par;
return getkid(st);
}
void sz(){
cout<<tsize<<endl;
}
void ls(){
int num=kids.size();
if(num==0)
cout<<"EMPTY"<<endl;
else if(num<=10)
for(auto it=kids.begin();it!=kids.end();it++)
cout<<it->first<<endl;
else{
auto it=kids.begin();
for(int i=0;i<5;i++,it++)
cout<<it->first<<endl;
cout<<"...\n";
it=kids.end();
for(int i=0;i<5;i++)
it--;
for(int i=0;i<5;i++,it++)
cout<<it->first<<endl;
}
}
void tree(){//树形结构目录
if(tsize==1)
cout<<"EMPTY"<<endl;
else if(tsize<=10){
if(this->update){
desc.clear();
treeall(&desc);
this->update=false;
}
for(auto it=desc.begin();it!=desc.end();it++)
cout<<*it<<endl;
}
else{
if(this->update){
desc.clear();
treefirst(5,&desc);
treelast(5,&desc);
this->update=false;
}
for(int i=0;i<5;i++)
cout<<desc[i]<<endl;
cout<<"...\n";
for(int i=9;i>=5;i--)
cout<<desc[i]<<endl;
}
}
private:
void treeall(vector<string>* vec){
vec->push_back(name);
for(auto it=kids.begin();it!=kids.end();it++)
it->second->treeall(vec);
}
void treefirst(int nums,vector<string>* vec){
vec->push_back(name);
if(--nums==0)
return;
int n=kids.size();
auto it=kids.begin();
while(n--){
int len=it->second->tsize;
if (len >= nums) {
it->second->treefirst(nums,vec);
return;
}
else {
it->second->treefirst(len,vec);
nums-= len;
}
it++;
}
}
void treelast(int nums,vector<string>* vec){
int n=kids.size();
auto it=kids.end();
while(n--)
{
it--;
int len=it->second->tsize;
if(len>=nums){
it->second->treelast(nums,vec);
return;
}
else{
it->second->treelast(len,vec);
nums-=len;
}
}
vec->push_back(name);
}
};
struct cmd{
string cmds[7]={"MKDIR","RM","CD","SZ","LS","TREE","UNDO"};
int type;
Dr* dir;
string arg;
cmd(string s){
for(int i=0;i<7;i++){
if(cmds[i]==s){
type=i;
if(i<3){
cin>>str;
arg=str;
}
return;
}
}
}
};
void solve(){
int tag;
cin>>tag;
Dr* now=new Dr("root",NULL);
vector<cmd*> cmdls;
for(int i=0;i<tag;i++){
cin>>str;
Dr* d;
cmd *ch=new cmd(str);
switch(ch->type){
case 0:
ch->dir=now->mkdir(ch->arg);
if(ch->dir==NULL)
cout<<"ERR"<<endl;
else{
cout<<"OK"<<endl;
cmdls.push_back(ch);
}
break;
case 1:
ch->dir=now->rm(ch->arg);
if(ch->dir==NULL)
cout<<"ERR"<<endl;
else{
cout<<"OK"<<endl;
cmdls.push_back(ch);
}
break;
case 2:
d=now->cd(ch->arg);
if(d==NULL)
cout<<"ERR"<<endl;
else{
cout<<"OK"<<endl;
ch->dir=now;
now=d;
cmdls.push_back(ch);
}
break;
case 3:
now->sz();break;
case 4:
now->ls();break;
case 5:
now->tree();break;
case 6:
{
bool su=false;
while(!su&&!cmdls.empty()){
ch=cmdls.back();
cmdls.pop_back();
if(ch->type==0)
su = now->rm(ch->arg)!=NULL;
else if(ch->type==1)
su=now->addkid(ch->dir);
else if(ch->type==2){
now=ch->dir;
su=true;
}
}
if(su) cout<<"OK"<<endl;
else cout<<"ERR"<<endl;
break;
}
}
}
}
int main(){
int m;
cin>>m;
while(m--)
solve();
return 0;
}