带配额文件系统 C++

好吧,调了好久还是没看出逻辑哪错了,最后只有60分,果然越复杂的函数出的bug越隐秘 看了其他人的写法发现也挺简单的,我用的数据结构复杂了,虽然思路一致,但出错了很难调

#include<bits/stdc++.h>
#define MAX  0x7fffffffffffffff
using namespace std;

struct node{
	string name;
	long long file_class;
	long long  ld,lr;//目录配额和后代配额
	long long  r_size,d_size;  //r_size 复用为普通文件大小 
	vector<node*> list; 
};
enum{
	FIL,DIR
}; 
//创建文件时,生成目录开始结点
node * Start_dir=NULL; 


node *root= new node({"root",DIR,MAX,MAX,0,0});

string ex_path(string &path)//路径解析器    匹配 路径   /[a-z0-9//]+ 
{	 
	long long i;	
	for( i=1;i<path.length();i++)
		if(path[i]=='/')
			break;
	if(i==path.length()) //当前目录创建
	{ 	
		if(i>1)
			path=path.substr(1,i-1);//文件名 
		return "now"; 
	}
	string str=path.substr(1,i-1);
	path=path.substr(i,path.length()-i);//解析完后剩余路径 
	return str;
 } 
node * Create_node(string name,long long file_class,long long  r_size=0,long long  d_size=0,long long  ld=MAX,long long  lr=MAX)
{
	node * p=new node({name,file_class,ld,lr,r_size,d_size});
	return p;
}
void Delete_node(node * Cur)  //删除这个文件的所有后代,不包括自己 
{
	if(Cur->file_class==DIR)
	{
		long long len=Cur->list.size();
		for(long long i=0;i<len;i++)
		{
			Delete_node(Cur->list[i]);
			delete Cur->list[i];
		}	
	}
	return;
}


bool Create_file(node * Cur,string cmd,long long fs,long long &dis) //返回的是执行该命令后文件的变化大小 
{
	//cout<<cmd<<" s "<<fs<<endl;
	 string name=ex_path(cmd);//路径名 
	 if(name=="now")
	 {
	 	long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==cmd)//覆盖 
	 		{
	 			if(Cur->list[i]->file_class==DIR)
	 				return false;
	 			dis=fs-Cur->list[i]->r_size;
	 			Cur->list[i]->r_size=fs;
	 			Cur->r_size+=dis;
				Cur->d_size+=dis;
	 			return true;
			 }
		 }
		Cur->list.push_back(Create_node(cmd,FIL,fs));
	 	dis=fs;
		Cur->r_size+=dis;
		Cur->d_size+=dis;
	 	return true;
	 } 
	 else//还需查找路径 
	 {
	 	long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==name)//找到对应名字,那函数就会在这个循环结束 
	 		{
	 			if(Cur->list[i]->file_class==DIR)
	 			{	
	 				
	 				bool re=Create_file(Cur->list[i],cmd,fs,dis);
	 				if(re)//创建成功则更新后代文件大小   这里不能检查文件配额,一定得分开写,因为之前的结点已经默认成功了 
	 				{
	 					Cur->r_size+=dis;
	 					return true; 
					 }
					 else
					 {
					 	return false;
					 }
				 }
				 else
				 {
				 	return false;
				 }
			 }
		 }
		//运行到这里时,说明未找到,需要创建目录
		node *p=Create_node(name,DIR);
		bool re=Create_file(p,cmd,fs,dis);//继续查找 
		if(re)
		{
			Cur->r_size+=dis;
			Cur->list.push_back(p);
			if(Start_dir==NULL)
				Start_dir=Cur;
			//cout<<cmd << " e "<<dis<<endl;
			return true;
		}
		else
		{
			Delete_node(p);
			delete p;
			return false;
		}
	 }
	 
} 

bool C_check_size(node * Cur,string cmd)//检查路径目录配额 
{
	string name=ex_path(cmd);
	if(name=="now")  //到达普通文件 
	 {
		if(Cur->r_size<=Cur->lr&&Cur->d_size<=Cur->ld)//检查当前目录 
			return true; 
		else 
			return false;
	 } 
	 else//还需查找路径 
	 {
	 	long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{	 
	 		if(Cur->list[i]->name==name)//找到对应名字,
	 		{
	 			//cout<<Cur->list[i]->name<<"   "<<" ld   "<<Cur->list[i]->ld <<"   lr   "<<Cur->list[i]->lr<<"   r_size   "<<Cur->list[i]->r_size<<"   d_size   "<<Cur->list[i]->d_size<<endl; 
	 			if(Cur->r_size<=Cur->lr&&Cur->d_size<=Cur->ld)//检查当前目录 
				 	return  C_check_size(Cur->list[i],cmd); //检查下一个目录 
				else 
					return false;
	 		} 
		 }
	 }
}
void C_restore(node *Cur, string cmd,long long &dis)//恢复执行之前所有普通文件,目录的大小   删除目录,普通文件另写 
{
	string name=ex_path(cmd);
	if(name=="now")  //到达普通文件 
	 {
	 	Cur->r_size-=dis;
	 	Cur->d_size-=dis;
	 	long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==cmd)//找到对应名字,
	 		{
	 			Cur->list[i]->r_size-=dis; 
	 			break; 
	 		} 
		 }
		return;
	 } 
	 else//还需查找路径 
	 {
	 	long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==name)//找到对应名字,
	 		{
	 			Cur->r_size-=dis;
				C_restore(Cur->list[i],cmd,dis); 
	 		} 
		 }
	 }
}

bool Remove(node * Cur,string cmd, long long& dis)
{
	string name=ex_path(cmd);
	if(name=="now")  //到达文件 
	 {
		long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==cmd)//找到文件 
	 		{
	 			dis=Cur->list[i]->r_size;
	 			if(Cur->list[i]->file_class==FIL)
				{
					Cur->r_size-=dis;
					Cur->d_size-=dis;
				}
				else
				{
					Cur->r_size-=dis;
				}
				//如果是DIR代表其后代所有大小,如果是普通文件代表其大小 
				Delete_node(Cur->list[i]);//有后代的话删除其后代 
				delete Cur->list[i];
				vector<node*>::iterator it=Cur->list.begin();
				Cur->list.erase(it+i);
				return true; 
			 }
			 
		 }
		return false;//找不到该文件 
	 } 
	 else//还需查找路径 
	 {
	 	long long len=Cur->list.size() ;
	 	 
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==name)//找到对应名字,
	 		{	
	 			if(Cur->list[i]->file_class==FIL)
	 				return false;
	 			bool  re=Remove(Cur->list[i],cmd,dis);
	 			if(re)
	 			{
	 				Cur->r_size-=dis;
	 				return true;
				 } 
				 else
				 {
				 	return false;
				 }
	 		} 
		 }
		return false;//找不到就报错 
	 }
}

bool Set_size(node * Cur,string cmd,long  long ld,long long   lr)
{
	if(cmd.length()==1)
	{
		if(ld<root->d_size||lr<root->r_size)
			return false;
		else
		{
			root->ld=ld;
			root->lr=lr;
			return true;
		}
	}
	string name=ex_path(cmd);
	if(name=="now")  //到达文件 
	 {
		long long len=Cur->list.size() ;
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==cmd)//找到文件 
	 		{
	 			if(Cur->list[i]->file_class==DIR)
				{
					if(lr<Cur->list[i]->r_size||ld<Cur->list[i]->d_size)
						return false;
					Cur->list[i]->ld=ld;
					Cur->list[i]->lr=lr;
					//cout<<Cur->list[i]->name<<"   "<<" ld   "<<Cur->list[i]->ld <<"   lr   "<<Cur->list[i]->lr<<"   r_size   "<<Cur->list[i]->r_size<<"   d_size   "<<Cur->list[i]->d_size<<endl; 
	 			
					return true;
					 }
				else 
					return false;	
			 }
		 }
		return false;//找不到该文件 
	 } 
	 else//还需查找路径 
	 {
	 	long long len=Cur->list.size() ;
	 	 
	 	for(long long i=0;i<len;i++)
	 	{
	 		if(Cur->list[i]->name==name)//找到对应名字,
	 		{
	 			if(Cur->list[i]->file_class==FIL)
	 				return false;
	 			bool re=Set_size(Cur->list[i],cmd,ld,lr);
	 			if(re)
	 				return true;
	 			return false;
	 		} 
		 }
		 return false;
	 }
}
int main()
{
	long long n;
	cin>>n;
	char ch;
	while(n--){
	
	cin>>ch;
	switch(ch){
		case 'C':
			{
				string cmd;
				long long size;
				cin>>cmd>>size;

				long long dis;
				Start_dir=NULL;
				bool re=Create_file(root,cmd,size,dis);
				if(re==false)
				{
					cout<<"N"<<endl;
				}
				else 
				{
					bool ccs=C_check_size(root,cmd);
					if(ccs)
					{
						cout<<"Y"<<endl;
					}
					else 
					{
						cout<<"N"<<endl;
						C_restore(root,cmd,dis);
						if(Start_dir!=NULL)
						//如果中途创建了目录 
						{
							long long len=Start_dir->list.size();
							node *p=Start_dir->list[len-1];
							Start_dir->list.pop_back();
							Delete_node(p);//删除后代 
							delete p; //删除本身	 
						}
					}
					
				}
				break;
			}
		case 'R':
			{
				string cmd;
				long long dis;
				cin>>cmd;
				Remove(root,cmd,dis);
				cout<<"Y"<<endl;
				break;
			}
		case 'Q':
			{
				string cmd;
				long long ld,lr;
				cin>>cmd>>ld>>lr;
				if(ld==0)
					ld=MAX;
				if(lr==0)
					lr=MAX;
				bool  re=Set_size(root,cmd,ld,lr);
				if(re)
					cout<<"Y"<<endl;
				else 
					cout<<"N"<<endl;
				break;
			}
	}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值