首页 > ACM题库 > HDU-杭电 > HDU 1413 文件系统-模拟-[解题报告] C++
2013
12-09

HDU 1413 文件系统-模拟-[解题报告] C++

文件系统

问题描述 :

Ignatius做了一个文件系统,为了测试他的文件系统是否能正常工作,他打算对他的文件系统做一些测试.

刚开始的时候文件系统里只有一个根目录.Ignatius将输入一系列合法的文件操作命令,请你给出文件系统应该给出的相应提示信息.

Ignatius的文件系统的文件操作命令包括:

1. CD [directory name] : 进入当前目录下名为[directory name]的子目录,如果成功,系统应提示"success",否则提示"no such directory".
2. MD [directory name] : 在当前目录下建立名为[directory name]的子目录,如果当前目录下已经存在名为[directory name]的子目录,则提示"directory already exist",否则提示"success".
3. RD [directory name] : 删除当前目录下名为[directory name]的子目录,如果当前目录下不存在名为[directory name]的子目录,或者名为[directory name]的子目录下还有文件或子目录,则提示"can not delete the directory",否则提示"success".
4. CREATE [file name] : 在当前目录下创建名为[file name]的文件,如果当前目录下已经存在名为[file name]的文件,则提示"file already exist",否则提示"success".
5. DELETE [file name] : 删除当前目录下名为[file name]的文件,如果当前目录下不存在名为[file name]的文件,则提示"no such file",否则提示"success".

以下是几个特殊说明:

1. 要从当前目录退回到上一级目录可以使用"CD .."命令来实现,我们约定根目录的上一级目录是其本身,任何一个目录下都不允许创建名为".."的子目录,如果有命令试图创建名为".."的子目录,则系统应反馈"directory already exist".
2. 要从当前目录直接退回到根目录可以使用"CD \"命令来实现,任何一个目录下都不允许创建名为"\"的子目录.
3. 为了方便编程,给出的任意一个[directory name]和[file name]都只包括大写字母(A-Z),并且长度都小于20.
4. 在同一个目录下允许存在同名的file和directory,但不允许出现同名的file或directory,在不同目录下则无此限制.
5. 刚开始的时候根目录下没有文件和子目录,当前目录就是根目录本身.
6. 如果一个操作是成功的,则应在当前文件系统的基础上执行相应的操作,以改变文件系统的状态.

输入:

输入数据只有一组,该组测试数据包含若干行,每行代表一条文件操作命令,我保证每一条命令都是符合命令格式的.
处理到文件结束.

输出:

对于每一条命令,请你给出系统的反馈信息,每个反馈信息占一行.

样例输入:

CD ACM
MD ACM
CD ACM
CREATE ACM
MD ACM
CD ACM
CD \
RD ACM
CD ACM
RD ACM
DELETE ACM
CD ..
RD ACM

样例输出:

no such directory
success
success
success
success
success
success
can not delete the directory
success
success
success
success
success

用链表生成一颗文件系统树,使用指针一定要小心内存问题。

代码较长,需细心,代码尽量写的清晰一点,便于检查。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct wenjian
{
	char name[25]; //当前文件夹名 
	char Fname[1005][25]; //当前文件夹下所有的文件。 
	wenjian *next[1005];//当前文件夹下所包含的文件夹 
	int sum; // 当前文件夹下的文件夹个数 
	int Fsum;// 当前文件夹下的文件个数 
	wenjian *father; //当前文件夹的根 
}*p; 
int main(int argc, char *argv[])
{
	char order[15],content[25]; int i,j,flag,id; 
	char note[6][50]={"success","no such directory","directory already exist",
	"can not delete the directory","file already exist","no such file"}; //输出数组
	p=new wenjian; wenjian *r=p;  //用r保存根
	strcpy(p->name,"\\"); p->sum=p->Fsum=0; p->father=p; //对根赋值 
	while(scanf("%s%s",order,content)!=EOF)
	{
		if(strcmp(order,"CD")==0) //CD切换 
		{
			flag=1;  //默认找不到 
			if(p->sum>0) //有文件夹 
			{
				for(i=0;i<p->sum;i++)
				if(strcmp(p->next[i]->name,content)==0) {flag=0; p=p->next[i]; break; } //找到了,进入下一级 
			}
			if(strcmp(content,"..")==0) //退回上一级目录 
			{
				p=p->father; flag=0;
			}
			if(strcmp(content,"\\")==0) //退回根目录 
			{
				p=r; flag=0;
			}
			printf("%s\n",note[flag]); 
			
		}
		else  if(strcmp(order,"MD")==0) //在当前目录下建立名为[directory name]的子目录 
		{
			flag=0; //默认找不到 
			if(p->sum>0)
			{
				for(i=0;i<p->sum;i++)
				if(strcmp(p->next[i]->name,content)==0){flag=2; break;}//有同名
				 
			}
			if(strcmp(content,"..")==0||strcmp(content,"\\")==0) flag=2; //不允许创建..和\子目录 
			printf("%s\n",note[flag]);
			if(flag==0) //创建子目录成功 ,更新当前目录所包含的文件夹 
			{
				wenjian *pp=new wenjian;
				strcpy(pp->name,content);
				pp->sum=pp->Fsum=0; pp->father=p;
				p->next[p->sum]=pp;
				(p->sum)++;
			} 	
		} 
		else if(strcmp(order,"RD")==0) //删除当前目录下名为[directory name]的子目录 
		{
			flag=0; //默认可以成功删除
			if(p->sum>0) //当前目录下有文件夹
			{
				for(i=0;i<p->sum;i++)
				if(strcmp(p->next[i]->name,content)==0) //找到了,看它是不是一个空文件夹 
				{
					if(p->next[i]->sum||p->next[i]->Fsum) {flag=3;break;} //不是空的 
					else { id=i; break;	} 
				} 
				if(i==p->sum) flag=3; //没有找到这个文件夹 	 
			}
			else flag=3; //没有文件夹
			printf("%s\n",note[flag]);
			if(flag==0) // 删除子目录成功,更新当前目录 
			{
				for(;i<(p->sum)-1;i++)
				{
					p->next[i]=p->next[i+1];
				}
				(p->sum)--;
			}	
		}
		else  if(strcmp(order,"CREATE")==0) //在当前目录下创建名为[file name]的文件
		{
			flag=0; //默认找不到 
			if(p->Fsum>0)
			{
				for(i=0;i<p->Fsum;i++)
				if(strcmp(p->Fname[i],content)==0){flag=4; break;}//有同名
				 
			}
			printf("%s\n",note[flag]);
			if(flag==0) //创建文件成功,更新文件 
			{
				strcpy(p->Fname[p->Fsum],content); (p->Fsum)+=1; 
			} 
		}
		else //删除当前目录下名为[file name]的文件 
		{
			flag=5;//默认没有这个文件
			if(p->Fsum>0)
			{
				for(i=0;i<p->Fsum;i++)
				{
					if(strcmp(p->Fname[i],content)==0) { flag=0; id=i;break;}
				}
			}
			printf("%s\n",note[flag]); 
			if(flag==0)  //删除文件成功,更新文件
			{
				for(;i<(p->Fsum)-1;i++)
				strcpy(p->Fname[i],p->Fname[i+1]);
				p->Fsum=(p->Fsum)-1;
			} 
		} 
	} 
	return 0;
}

 

解题报告转自:http://blog.csdn.net/liang5630/article/details/12419861


  1. 这道题目虽然简单,但是小编做的很到位,应该会给很多人启发吧!对于面试当中不给开辟额外空间的问题不是绝对的,实际上至少是允许少数变量存在的。之前遇到相似的问题也是恍然大悟,今天看到小编这篇文章相见恨晚。

  2. #include <cstdio>
    #include <cstring>

    const int MAXSIZE=256;
    //char store[MAXSIZE];
    char str1[MAXSIZE];
    /*
    void init(char *store) {
    int i;
    store['A']=’V', store['B']=’W',store['C']=’X',store['D']=’Y',store['E']=’Z';
    for(i=’F';i<=’Z';++i) store =i-5;
    }
    */
    int main() {
    //freopen("input.txt","r",stdin);
    //init(store);
    char *p;
    while(fgets(str1,MAXSIZE,stdin) && strcmp(str1,"STARTn")==0) {
    if(p=fgets(str1,MAXSIZE,stdin)) {
    for(;*p;++p) {
    //*p=store[*p]
    if(*p<’A’ || *p>’Z') continue;
    if(*p>’E') *p=*p-5;
    else *p=*p+21;
    }
    printf("%s",str1);
    }
    fgets(str1,MAXSIZE,stdin);
    }
    return 0;
    }