复杂程设题之A - 咕咕东的目录管理器(C++

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值