带配额的文件系统

这篇博客介绍了一个模拟文件系统的过程,使用静态树作为数据结构,详细阐述了节点信息设计、创建文件、删除文件及设置配额值等操作。通过Cdo()、Rdo()、Qdo()三个函数实现路径检查、文件检查、配额检查等功能,确保文件系统的正确运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
这道题目是对文件系统的模拟。

第一步,选取“静态树”作为本题的数据结构。

第二步,设计结点信息。需要包括 ①孩子结点信息 ② 目录配额与后代配额的最大值 ③ 当前目录配额与后代配额 ④ 父节点信息 ⑤ 区分普通文件与目录 ⑥ 若是普通文件,则需记录文件大小。

第三步,设计创建普通文件模块。

在这里插入图片描述

第四步,删除文件模块。

在这里插入图片描述

第五步,设置配额值。

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int maxn = 4e6+5;
typedef long long  ll;
struct Node{
	map<string, int> child;
	ll max_ld1, max_ld2;
	ll ld1, ld2;
	ll fsize;
	int flag;
	int fa_id;
};
Node node[maxn];
int n, index = 0; // index 记录当前操作结点 

vector< pair<int, string> > reback;  // 记录输入的路径 

void Reback()  // 按照输入的路径清除树上的结点 
{
	for(int i = 0; i < reback.size(); i++)
	{
		int f_id = reback[i].first;
		string son_name = reback[i].second;
		node[f_id].child.erase(son_name);
	}
}

string Cdo()
{
	int id = 0;
	int tindex = index;  // 记录开始的编号,销毁路径前恢复到 index 
	string path; ll fsize;
	int p = 1;
	cin>>path>>fsize;
	int last = path.rfind("/");
	reback.clear();
// 第一步:路径检查 
	while(p < last)
	{
		string t = "";
		for(;p < last && path[p] != '/'; p++)
		{
			t += path[p];
		}
		p++;
		if(node[id].child.find(t) == node[id].child.end())
		{  // 没找到,则创建路径 
			node[id].child[t] = ++index;
			node[index].fa_id = id;
			node[index].flag = 2;
			node[index].max_ld1 = LLONG_MAX / 3;
			node[index].max_ld2 = LLONG_MAX / 3;
			node[index].ld1 = 0;
			node[index].ld2 = 0;
			reback.push_back(make_pair(id, t));
			id = index;
		}else{ // 找到路径,进行判断 
			int sonid = node[id].child[t];
			if(node[sonid].flag == 1) 
			{  index = tindex;  
			   Reback(); 
			   return "N";
			}
			id = sonid; 
		}
	}
	
// 第二步:文件检查
	  string f_name = path.substr(last + 1);
	  if(node[id].child.find(f_name) != node[id].child.end())
	  {
	  	  int sonid = node[id].child[f_name];
	  	  if(node[sonid].flag == 2)
	  	  {
	  	      index = tindex;
			  Reback();
			  return "N";	
		  }
	  }
      ll py;
      if(node[id].child.find(f_name) == node[id].child.end()) py = fsize;
      else py = fsize - node[node[id].child[f_name]].fsize;
      
      // 检查目录配额 
      if(node[id].ld1 + py > node[id].max_ld1)
	  {
      	  index = tindex;
      	  Reback();
      	  return "N";
	  }
	  
	  // 检查所有祖先结点的后代配额 
	  int temp_id = id;
	  while(temp_id != -1)
	  {
	     if(node[temp_id].ld2 + py > node[temp_id].max_ld2)
		 {
		     index = tindex;
			 Reback();
			 return "N";	
		 }	
		 temp_id = node[temp_id].fa_id;
	  } 
	  
	  if(node[id].child.find(f_name) == node[id].child.end())
	  {  // 配额够用的情况下,创建新的文件
	      node[id].child[f_name] = ++index;
		  node[index].fa_id = id;
		  node[index].flag = 1;
		  node[index].fsize = fsize; 
	  } else{
	     // 配额够用的情况下,替换原有的文件
		  int sonid = node[id].child[f_name];
		  node[sonid].fsize = fsize; 	
	  }
	  
	  node[id].ld1 += py;
	  int temp_id2 = id;
	  while(temp_id2 != -1)
	  {
	  	 node[temp_id2].ld2 += py;
	  	 temp_id2 = node[temp_id2].fa_id;
	  }
	  return "Y";
}

string Rdo()
{
    string path;
	cin>>path;
	int last = path.rfind("/");
	int p = 1;
	int id = 0;
	
// 第一步: 路径检查 
    while(p < last)
	{
	   string t = "";
	   for(; p < last && path[p] != '/'; p++)
	   {
	       t += path[p];	
	   }	
	   p++;
	   if(node[id].child.find(t) == node[id].child.end()) return "Y";
	   else{
	   	   int sonid = node[id].child[t];
	   	   if(node[sonid].flag == 1) return "Y";
	   	   id = sonid;
	   }
	}	
	
// 第二步: 文件删除
    string f_name = path.substr(last + 1);
	if(node[id].child.find(f_name) == node[id].child.end()) return "Y";
	else{
		 int sonid = node[id].child[f_name];
		 if(node[sonid].flag == 1)
		 {  // 是普通文件 
		 	node[id].child .erase(f_name);
		 	node[id].ld1 -= node[sonid].fsize;
		 	int temp_id = id;
		 	while(temp_id != -1)
		 	{
		 	    node[temp_id].ld2 -= node[sonid].fsize;
				temp_id	= node[temp_id].fa_id;
			}
		 }else{  // 是目录 
		 	node[id].child.erase(f_name);
		 	int temp_id = id;
		 	while(temp_id != -1)
		 	{
		 	   node[temp_id].ld2 -= node[sonid].ld2;
			   temp_id = node[temp_id].fa_id;	
			}
		 }
	} 
	return "Y";
}

string Qdo()
{
	 string path;
	 ll set_ld1, set_ld2;
	 cin>>path>>set_ld1>>set_ld2;
	 if(set_ld1 == 0) set_ld1 = LLONG_MAX / 3;
	 if(set_ld2 == 0) set_ld2 = LLONG_MAX / 3;
	 int last = path.rfind("/");
	 int p = 1;
	 int id = 0;
	 while(p < last)
	 {
	 	 string t = "";
	 	 for(;p < last && path[p] != '/'; p++)
	 	 {
	 	     t += path[p];	
		 }
		 p++;
		 if(node[id].child.find(t) == node[id].child.end()) return "N";  // 路径不存在
		 else{
		 	int sonid = node[id].child[t];
		 	if(node[sonid].flag == 1) return "N";  // 路径错误
			id = sonid; 
		 } 
	 }
	 
	 string f_name = path.substr(last + 1);
	 int qnode;
	 if(id == 0) qnode = 0; // 根目录 
	 else{
	     if(node[id].child.find(f_name) == node[id].child.end()) return "N";
		 else qnode = node[id].child[f_name];	
	 } 
	 if(node[qnode].flag == 1) return "N";  // 是普通文件 
	 else{  // 是目录 
	 	if(set_ld1 < node[qnode].ld1 || set_ld2 < node[qnode].ld2) return "N";
	 	else{
	 		node[qnode].max_ld1 = set_ld1;
	 		node[qnode].max_ld2 = set_ld2;
	 		return "Y";
		 }
	 }
}

int main()
{
	// 根目录 
	node[0].fa_id = -1;
	node[0].flag = 2;
	node[0].max_ld1 = LLONG_MAX / 3;
	node[0].max_ld2 = LLONG_MAX / 3;
	node[0].ld1 = 0;
	node[0].ld2 = 0;
	
	char c;
	string str;
	
	cin>>n;
	for(int i = 0; i < n; i++)
	{
		cin>>c;
		if(c == 'C')
		{
			cout<<Cdo()<<endl;
		}
		if(c == 'R')
		{
			cout<<Rdo()<<endl;
		}
		if(c == 'Q')
		{
			cout<<Qdo()<<endl;
		}
	}	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Matts Tian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值