算法与数据结构实验题 6.41 文件管理器

实验任务

操作系统具有对计算机硬件资源管理和调度的功能。文件是对占用了硬盘一定空间的对象的描述和抽象。考虑一般的文件具有文件名、大小和创建时间。文件管理在任何操作系统中都是必不可少的。文件管理器是用户用来观察和操作文件的一个软件。考虑一个简易的文件管理器,用户可以通过这个简易的文件管理器对某个目录下文件最大/小、文件名(字符串)字典序最大/最小的一些文件,即按XX排序功能,此外文件管理器具有删除和添加文件的功能。输入保证目录只有一级,操作随机。

数据输入&输出

第1行输入一个Q(1<=Q<=100000),表示操作的次数。

第2-Q+1行输入一行操作序列

操作序列的格式为 op args

当op=1,即第一种操作时,args的格式为 folder name size 表示将要在某个folder目录(1<=folder<=5的整数)下添加文件名为name(1<=name<=100000的整数)的文件,文件大小为size(1<=size<=100000的整数),如果文件名重复,就先删除原来的文件再进行1操作;

当op=2,即第二种操作时,args的格式为 folder name表示将要在某个folder目录(1<=folder<=5的整数)下删除文件名为name(1<=name<=100000的整数)的文件,如果文件名不存在,操作不执行;

当op=3,即第三种操作时,args的格式为 folder k 表示输出某个目录下文件大小最大至第k大的文件名,如果大小相同按文件名数字从小到大输出,如果不满k个文件只需要输出已有的文件名,如果文件夹为空或不存在则输出一个空行;

当op=4,即第四种操作时,args的格式为 folder k 表示输出某个目录下文件名数字大小最小至第k小的文件名,如果不满k个文件只需要输出已有的文件名,如果文件夹为空或不存在则输出一个空行;

保证1<= k <=10

输入示例

10
2 3 74071
3 1 2
3 2 8
2 3 71337
3 3 7
3 2 7
4 2 10
4 3 6
4 3 4
3 1 4

输出示例










//以上为八个空行

代码

#include<bits/stdc++.h>
using namespace std;

int T,opt,f,n,s,k;
struct doc{
	int name,size;
};
class docSort {
public:
	bool operator() (const doc &a,const doc &b) const {
		if(a.size!=b.size) return a.size>b.size;
		else return a.name<b.name;
	}
};
set<doc,docSort>folder[10];
map<int,int>siz[10];

int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&opt);
		if(opt==1) {
			scanf("%d%d%d",&f,&n,&s);
			if(siz[f][n]) folder[f].erase(folder[f].find({n,siz[f][n]}));
			folder[f].insert({n,s});
			siz[f][n]=s;
		}
		else if(opt==2) {
			scanf("%d%d",&f,&n);
			if(siz[f].find(n)!=siz[f].end()) {
				auto it=folder[f].find({n,siz[f][n]});
				if(it!=folder[f].end()) {
					folder[f].erase(it);
					auto p=siz[f].find(n);
					siz[f].erase(p);
				}
			}
		}
		else if(opt==3) {
			scanf("%d%d",&f,&k);
			for(auto it=folder[f].begin();it!=folder[f].end()&&k;++it,--k) {
				printf("%d",it->name);
				auto p=it;
				if(++p!=folder[f].end()&&k-1) printf(" ");
			}
			printf("\n");
		}
		else {
			scanf("%d%d",&f,&k);
			for(auto it=siz[f].begin();it!=siz[f].end()&&k;++it,--k) {
				printf("%d",(*it).first);
				auto p=it;
				if(++p!=siz[f].end()&&k-1) printf(" ");
			}
			printf("\n");
		}
	}
	return 0;
}

思路
本题模拟的内容极为复杂易错,是一题考验细心程度的题

这里我们利用set的去重、自排序,以及map的映射与自排序性质,来实现本题的模拟,注意以下几点

  1. map在查找不存在的映射时,会将此映射作为空项放入红黑树中,影响后续的查找,因此需要先确认要查找的映射是否存在,再进行map的调用
  2. 删除操作时指针会随之变为空指针,不可再利用,因此删除时需要new一个新指针出来
posted @ 2024-11-25 23:27  Severj  阅读(139)  评论(0)    收藏  举报