文件系统
Ignatius做了一个文件系统,为了测试他的文件系统是否能正常工作,他打算对他的文件系统做一些测试.
刚开始的时候文件系统里只有一个根目录.Ignatius将输入一系列合法的文件操作命令,请你给出文件系统应该给出的相应提示信息.
Ignatius的文件系统的文件操作命令包括:
- CD [directory name] : 进入当前目录下名为[directory name]的子目录,如果成功,系统应提示"success",否则提示"no such directory".
- MD [directory name] : 在当前目录下建立名为[directory name]的子目录,如果当前目录下已经存在名为[directory name]的子目录,则提示"directory already exist",否则提示"success".
- RD [directory name] : 删除当前目录下名为[directory name]的子目录,如果当前目录下不存在名为[directory name]的子目录,或者名为[directory name]的子目录下还有文件或子目录,则提示"can not delete the directory",否则提示"success".
- CREATE [file name] : 在当前目录下创建名为[file name]的文件,如果当前目录下已经存在名为[file name]的文件,则提示"file already exist",否则提示"success".
- DELETE [file name] : 删除当前目录下名为[file name]的文件,如果当前目录下不存在名为[file name]的文件,则提示"no such file",否则提示"success".
以下是几个特殊说明:
- 要从当前目录退回到上一级目录可以使用"CD …“命令来实现,我们约定根目录的上一级目录是其本身,任何一个目录下都不允许创建名为”…“的子目录,如果有命令试图创建名为”…“的子目录,则系统应反馈"directory already exist”.
- 要从当前目录直接退回到根目录可以使用"CD “命令来实现,任何一个目录下都不允许创建名为”"的子目录.
- 为了方便编程,给出的任意一个[directory name]和[file name]都只包括大写字母(A-Z),并且长度都小于20.
- 在同一个目录下允许存在同名的file和directory,但不允许出现同名的file或directory,在不同目录下则无此限制.
- 刚开始的时候根目录下没有文件和子目录,当前目录就是根目录本身.
- 如果一个操作是成功的,则应在当前文件系统的基础上执行相应的操作,以改变文件系统的状态.
Input
输入数据只有一组,该组测试数据包含若干行,每行代表一条文件操作命令,我保证每一条命令都是符合命令格式的.
处理到文件结束.
Output
对于每一条命令,请你给出系统的反馈信息,每个反馈信息占一行.
Sample Input
CD ACM
MD ACM
CD ACM
CREATE ACM
MD ACM
CD ACM
CD
RD ACM
CD ACM
RD ACM
DELETE ACM
CD …
RD ACM
Sample Output
no such directory
success
success
success
success
success
success
can not delete the directory
success
success
success
success
success
思路:
利用树结构来完成操作
数据结构:
typedef struct directory{
string directoryname;//目录名
int num;//文件和目录的数量
struct directory *root;//根节点
struct directory *father;//父亲节点
vector<struct directory *> son;//子目录
vector<string> file;//该目录下包含的文件
}directory;
注意由于根节点的root节点和father节点初始化为NULL,所以当CD操作要进入根节点目录时要进行特殊处理,否则程序会崩溃。
/*CD操作需判fa是否为根节点,由于根节点对CD ..和CD \操作返回自身,但ro->root=NULL,ro->father=NULL,
所以若没有对根节点的特殊判别程序会崩溃*/
directory* CD(directory *fa,string name){
int f=0;
int i;
if(name==".."&&fa!=ro){
cout<<"success"<<endl;
return fa->father;
}
if(name=="\\"&&fa!=ro){
cout<<"success"<<endl;
return fa->root;
}
if((name==".."||name=="\\")&&fa==ro){
cout<<"success"<<endl;
return ro;
}//对根节点的特殊操作
for(i=0;i<fa->son.size();i++){
if(fa->son[i]->directoryname==name){
f=1;
break;
}
}
if(f==1){
cout<<"success"<<endl;
return fa->son[i];
}
else{
cout<<"no such directory"<<endl;
return fa;
}
}//进入当前目录下名为[directory name]的子目录
总之使用指针时一定要注意,不要调用空指针或已经被释放空间的指针。
完整代码如下:
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
using namespace std;
typedef struct directory{
string directoryname;//目录名
int num;//文件和目录的数量
struct directory *root;//根节点
struct directory *father;//父亲节点
vector<struct directory *> son;//子目录
vector<string> file;//该目录下包含的文件
}directory;
directory* ro;//定义根节点
directory *init(directory *r){
r=new directory;
r->directoryname="\\";
r->num=0;
r->root=NULL;
r->father=NULL;
r->son.clear();
r->file.clear();
return r;
}//初始化操作
/*CD操作需判fa是否为根节点,由于根节点对CD ..和CD \操作返回自身,但ro->root=NULL,ro->father=NULL,
所以若没有对根节点的特殊判别程序会崩溃*/
directory* CD(directory *fa,string name){
int f=0;
int i;
if(name==".."&&fa!=ro){
cout<<"success"<<endl;
return fa->father;
}
if(name=="\\"&&fa!=ro){
cout<<"success"<<endl;
return fa->root;
}
if((name==".."||name=="\\")&&fa==ro){
cout<<"success"<<endl;
return ro;
}//对根节点的特殊操作
for(i=0;i<fa->son.size();i++){
if(fa->son[i]->directoryname==name){
f=1;
break;
}
}
if(f==1){
cout<<"success"<<endl;
return fa->son[i];
}
else{
cout<<"no such directory"<<endl;
return fa;
}
}//进入当前目录下名为[directory name]的子目录
directory* MD(directory *fa,string name){
int f=0;
int i;
for(i=0;i<fa->son.size();i++){
if(fa->son[i]->directoryname==name){
f=1;
break;
}
}
if(f==1||name==".."){
cout<<"directory already exist"<<endl;
}
else{
directory *p;
p=new directory;
p->directoryname=name;
p->num=0;
p->root=ro;
p->father=fa;
p->file.clear();
fa->son.push_back(p);//向vector的尾部插入元素
fa->num++;
cout<<"success"<<endl;
}
return fa;
}//在当前目录下建立名为[directory name]的子目录
directory* RD(directory *fa,string name){
int f=0;
int i;
for(i=0;i<fa->son.size();i++){
if(fa->son[i]->directoryname==name&&fa->son[i]->num==0){
f=1;
break;
}
}
if(f==1){
fa->son.erase(fa->son.begin()+i);//删除第i个元素
fa->num--;
cout<<"success"<<endl;
}
else if(f==0){
cout<<"can not delete the directory"<<endl;
}
return fa;
}//删除当前目录下名为[directory name]的子目录
directory* create(directory *fa,string name){
int f=0;
int i;
for(i=0;i<fa->file.size();i++){
if(fa->file[i]==name){
f=1;
break;
}
}
if(f==1){
cout<<"file already exist"<<endl;
}
else{
fa->file.push_back(name);
fa->num++;
cout<<"success"<<endl;
}
return fa;
}//在当前目录下创建名为[file name]的文件
directory* del(directory *fa,string name){
int f=0;
int i;
for(i=0;i<fa->file.size();i++){
if(fa->file[i]==name){
f=1;
break;
}
}
if(f==0){
cout<<"no such file"<<endl;
}
else{
fa->file.erase(fa->file.begin()+i);//删除第i个元素
fa->num--;
cout<<"success"<<endl;
}
return fa;
}//删除当前目录下名为[file name]的文件
void clear(directory *p){
if(p->son.empty()){
delete p;
return;
}
else{
for(int i=0;i<p->son.size();i++){
clear(p->son[i]);
}
}
}//释放内存
int main(void){
string str,na;
directory *q;//当前目录
q=NULL;
ro=init(ro);
q=ro;
while(cin>>str){
if(str=="CD"){
cin>>na;
q=CD(q,na);
}
if(str=="MD"){
cin>>na;
q=MD(q,na);
}
if(str=="RD"){
cin>>na;
q=RD(q,na);
}
if(str=="CREATE"){
cin>>na;
q=create(q,na);
}
if(str=="DELETE"){
cin>>na;
q=del(q,na);
}
}
clear(ro);
return 0;
}