第九周作业 A题

A-目录管理器

题目描述:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

解题思路:
这道题我觉得靠我们的更多是一个全局观,和一个分部份,和功能的能力,注意封装,也是代码能力的提升。
有些时候写东西最忌讳牵一发而动全身,如果我们分开去写的话,能增加可更改性还有更有可能分工合作
首先,可以将这个目录作为一棵树去维护。
然后就是对于指令的操作,将指令封装
再次就是一项一项实现功能
这里注意有一条是撤回上一步,那我们在每一次执行成功命令之后都要记录下来,当遇到撤回时,就可以利用起来了

#include<stdio.h>
#include<string.h>
#include<map> 
#include<vector>
using namespace std;
char tmps[20];
struct Directory{
	string name;
	map<string, Directory*> children;
	 Directory* parent;
	 int subtreesize;
	 vector<string>* tenDescendants;
	 bool updated;
	 Directory(string name, Directory* parent)
	 {
	 	this->name=name;
	 	this->parent=parent;
	 	this->subtreesize=1;
	 	updated=true;
	 	tenDescendants = new vector<string>;
	 }
	 public:
	 	bool addChild(Directory* ch)
	 	{
	 		if(children.find(ch->name)!=children.end())
	 			return false;
	 		children[ch->name]=ch;
	 		maintain(+ch->subtreesize);
	 		return true;
		 }
	 	Directory* getChild(string name)
	 	{
	 		auto it=children.find(name);
	 		if(it==children.end())
	 			return NULL;
	 		return it->second;
		 }
	 	Directory* mkdir(string name)
		 {	
		 	auto it=children.find(name);
		 	if(it!=children.end()) return NULL;
		 	Directory* ch=new Directory(name,this);
		 	children[name]=ch;
		 	maintain(+1);
		 	return ch;
		 }
	 	Directory* rm(string name)
		 {	
		 	map<string, Directory*>::iterator it=children.find(name);
		 	if(it==children.end()) return NULL;
		 	maintain(-1 * it->second->subtreesize);
		 	children.erase(it);
		 	return it->second;
		 }
	 	Directory* cd(string name)
	 	{
	 		if(name=="..")
	 		 	return this->parent;
	 		return getChild(name);
		 }
		 void maintain(int delta)
		 {
		 	updated=true;
		 	subtreesize+=delta;
		 	if(parent!=NULL)
		 		parent->maintain(delta);
		  } 
	 	void sz()
	 	{
	 		printf("%d\n",this->subtreesize);
		 }
	 	void ls()
	 	{
	 		int sz=children.size();
	 		if(sz==0) printf("EMPTY\n");
	 		else if(sz<=10){
	 			for(auto &entry : children)
	 			printf("%s\n",entry.first.c_str());
			 }
			 else{
			 	auto it=children.begin();
			 	for(int i=0;i<5;i++) printf("%s\n",it->first.c_str());
			 	printf("...\n");
			 	it=children.end();
			 	for(int i=0;i<5;i++) it--;
			 	for(int i=0;i<5;i++) printf("%s\n",it->first.c_str());
			 }
		 }
	 	void tree()
	 	{
	 		if(subtreesize==1) printf("EMPTY\n");
	 		else if(subtreesize<=10)
			 {
	 			if(this->updated)
	 			{
	 				tenDescendants->clear();
	 				treeAll(tenDescendants);
	 				this->updated=false;
				 }
				 for(int i=0;i<subtreesize;i++) printf("%s\n",tenDescendants->at(i).c_str());
			 }
			 else
			 {
			 	if(this->updated)
			 	{
			 		tenDescendants->clear();
			 		treeFirstSome(5,tenDescendants);
			 		treeLastSome(5,tenDescendants);
			 		this->updated=false;
				 }
				 for(int i=0;i<5;i++) printf("%s\n",tenDescendants->at(i).c_str());
				 printf("...\n");
				 for(int i=9;i>=5;i--) printf("%s\n",tenDescendants->at(i).c_str());
			 }
		 }
	private:
		void treeAll(vector<string>* bar)
		{
			bar->push_back(name);
			for(auto &entry : children)
			 	entry.second->treeAll(bar);
		}
		void treeFirstSome(int num,vector<string>* bar)
		{
			bar->push_back(name);
			if(--num==0) return;
			int n=children.size();
			auto it=children.begin();
			while(n--)
			{
				int sts=it->second->subtreesize;
				if(sts>=num)
				{
					it->second->treeFirstSome(num,bar);
					return;
				}	
				else
				{	
					it->second->treeFirstSome(sts,bar);
					num-=sts;
				}
				it++;
			}
		}	
		void treeLastSome(int num,vector<string>* bar)
		{
			int n=children.size();
			auto it=children.end();
			while(n--)
			{
				it--;
				int sts=it->second->subtreesize;
				if(sts>=num)
				{
					it->second->treeLastSome(num,bar);
					return;
				}	
				else
				{	
					it->second->treeLastSome(sts,bar);
					num-=sts;
				}
			}
			bar->push_back(name);
		}
	 	
};
struct Command{
	const string CMD_NAMES[7]={"MKDIR","RM","CD","SZ","LS","TREE","UNDO"};
	int type;
	string arg;
	Directory* tmpDir;
	Command(string s)
	{
		//cout<<s<<endl;
		for(int i=0;i<7;i++) if(s==CMD_NAMES[i]){
				type=i;
				if(type<3) scanf("%s",tmps),arg=tmps;
			 return;
		} 
	}
};

void solve()
{
	int n;
	scanf("%d",&n);
	Directory* now=new Directory("root",NULL);
	vector<Command*> cmdlist;
	while(n--)
	{
		scanf("%s",tmps);
		Command* cmd=new Command(tmps);
		//cout<<cmd->type<<endl;
		switch(cmd->type)
		{
			case 0: case 1:{
				cmd->tmpDir = cmd->type==0 ? now->mkdir(cmd->arg) : now->rm(cmd->arg);
				if(cmd->tmpDir==NULL) printf("ERR\n"); 
				else{
					printf("OK\n");
					cmdlist.push_back(cmd);
				}
				break;
			}
			case 2:{
				Directory* ch=now->cd(cmd->arg);
				if(ch==NULL) printf("ERR\n");
				else{
					printf("OK\n");
					cmd->tmpDir=now;
					now=ch;
					cmdlist.push_back(cmd);
				}
				break;
			}
			case 3:{
				now->sz();
				break;
			}
			case 4:{
				now->ls();
				break;
			}
			case 5:{
				now->tree();
				break;
			}
			case 6:{
				bool success=false;
				while(!success&&!cmdlist.empty())
				{
					cmd=cmdlist.back();
					cmdlist.pop_back();
					switch(cmd->type)
					{
						case 0: success=now->rm(cmd->arg)!=NULL; break;
						case 1: success=now->addChild(cmd->tmpDir); break;
						case 2: now=cmd->tmpDir;success=true; break;
					}
				}
				printf(success ? "OK\n" : "ERR\n");
			}
		 } 
	}
}
int main(){
//		freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	int t;
	scanf("%d",&t);
	while(t--) solve();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值