您的位置:首页 > 其它

文件系统

2015-08-10 23:06 323 查看
Problem Description

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. 如果一个操作是成功的,则应在当前文件系统的基础上执行相应的操作,以改变文件系统的状态.


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


这个是ACMCODER Online Judge上的一道原题。我们可以把这个文件系统想成一棵树树,如下图所示。


实现数据结构:
  1.链表(推荐)
  2.数组
  因为文件树是一个不规则的树,如果用数组实现则会浪费很多空间,当然我们也可以每次给数组重新设定大小,但这样代价太大,所以这里我们代用链表来实现。我们的系统由文件夹和文件组成,所以我们定义如下数据结构
文件:
  文件这里用的是一个双向链表,也可以采用单项链表

// 在一个文件夹下的所有文件以链表形式存放
class File {
File pre; // 前一个目录
File next; // 后一个目录
String name; // 目录名称

public File(String name) {
this.name = name;
}
}


文件夹:

  文件包含子目录,父目录,文件三个部分组成。

// 在同一目录下的所有子目录以链表形式存放
class Dir {
Dir childDir;    // 该目录下的所有子目录
Dir pre;         // 目录的前一个目录(就是该目录的兄弟目录)
Dir next;        // 目录的后一个目录
Dir parent;      // 该目录的父目录
int dirCount;    // 目录个数
String name;     // 目录名称
File file;       // 该文件夹下的文件,以链表形式存放
int fileCount;   // 文件个数
}


下面是完整的Java代码实现。

import java.util.Scanner;

public class Main {
static double PI = 3.1415927;

public static void main(String[] args) {

FileSystem fileSystem = new FileSystem();
fileSystem.filesystem();
}
}

class FileSystem {

// 定义根目录
final static String ROOT = "root";

// 在同一目录下的所有子目录以链表形式存放
class Dir {
Dir childDir;    // 目录的头结点,头结点为null
Dir pre;         // 前一个目录
Dir next;        // 后一个目录
Dir parent;      // 该目录的父目录
int dirCount;    // 目录个数
String name;     // 目录名称
File file;       // 该文件夹下的文件,以链表形式存放
int fileCount;   // 文件个数

public Dir(String name) {
this.name = name;
init();
}

void init() {
file = new File("rootFile");
dirCount = 0;
}

boolean delete(String dirName) {
if (dirCount == 0) { // 如果当前目录没有子目录,则删除失败
return false;
}
Dir myhead = childDir; // 从第一目录开始
while (myhead != null) {
if (myhead.name.equals(dirName)) {

if (myhead.dirCount != 0) { // 如果该目录下还有子目录,则删除失败
return false;
}
dirCount--;
if (myhead.pre != null) {
myhead.pre.next = myhead.next; // 删除该结点
myhead.next.pre = myhead.pre;
myhead = null;
return true;
} else {                        //该节点为头结点
if (myhead.next == null) {
childDir = null;
}else {
childDir = myhead.next;
childDir.pre = null;
myhead = null;
}
return true;
}
}
myhead = myhead.next; // 依次循环
}
return false;
}

boolean add(String dirName) {
if (search(dirName) != null) { // 查找该目录文件已经存在
return false;
}

Dir dir = new Dir(dirName);

// 让该目录的子目录都指向自己
dir.parent = this;

if (dirCount == 0) { // 如果当前目录下没有子目录则,则直接插入
childDir = dir;
childDir.next = null;
} else {
Dir myhead = childDir;
while (myhead.next != null) {
myhead = myhead.next;
}
myhead.next = dir;
dir.pre = myhead;
dir.next = null;
}
dirCount++;
return true;
}

Dir search(String dirName) { // 查找该目录文件是否存在,存在返回该目录,否则返回null
if (dirCount == 0) {
return null;
}
Dir myhead = childDir;
while (myhead != null) {
if (myhead.name.equals(dirName)) {
return myhead;
}
myhead = myhead.next;
}
return null;
}

Dir parent() {

// 如果当前目录是根目录,则返回自己
if (ROOT.equals(name)) {
return this;
}
// 如果不是根目录,则返回父目录
return parent;
}

Dir child(String childName) {
return search(childName);
}

boolean deleteFile(String fileName) {
if (fileCount == 0) { // 如果当前目录没有子目录,则删除失败
return false;
}
File myhead = file; // 从第一目录开始
while (myhead!= null) {
if (myhead.name.equals(fileName)) {
fileCount--;
if (myhead.pre != null) {
myhead.pre.next = myhead.next; // 删除该结点
myhead.next.pre = myhead.pre;
myhead = null;
return true;
} else {
if (myhead.next==null) {
file = null;
}else {
file = myhead.next;
file.pre = null;
myhead = null;
}
return true;
}

}
myhead = myhead.next; // 依次循环
}
return false;
}

boolean addFile(String fileName) {
if (searchFile(fileName)) { // 查找该目录文件已经存在
return false;
}
File newFile = new File(fileName);
if (fileCount == 0) { // 如果当前目录下没有子目录则,则直接插入
file = newFile;
file.next = null;
} else {
File myhead = file;
while (myhead.next != null) {
myhead = myhead.next;
}
myhead.next = newFile;
newFile.pre = myhead;
newFile.next = null;
}
fileCount++;
return true;
}

boolean searchFile(String fileName) { // 查找该目录文件是否存在,存在返回true,否则返回false
if (fileCount == 0) {
return false;
}
File myhead = file;
while (myhead != null) {
if (myhead.name.equals(fileName)) {
return true;
}
myhead = myhead.next;
}
return false;
}
}

// 在同一目录下的所有子目录以链表形式存放
class File {
File pre; // 前一个目录
File next; // 后一个目录
String name; // 目录名称

public File(String name) {
this.name = name;
}
}

void filesystem() {
Dir root = new Dir(ROOT);
Dir rootDir = root;
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String commander = sc.next();
String content = sc.next();
switch (commander) {
case "CD": {
if (content.equals("..")) {
root = root.parent();
System.out.println("success");
} else if (content.equals("\\")) {
root = rootDir;
System.out.println("success");
} else {
Dir chlid = root.child(content);
if (chlid == null) {
System.out.println("no such directory");
} else {
root = chlid;
System.out.println("success");
}
}
}
break;
case "MD": {
if (content.equals("..")) {
System.out.println("directory already exist");
} else {
if (root.add(content)) {
System.out.println("success");
} else {
System.out.println("directory already exist");
}
}
}
break;
case "RD": {
if (root.delete(content)) {
System.out.println("success");
} else {
System.out.println("can not delete the directory");
}
}
break;
case "CREATE": {
if (root.addFile(content)) {
System.out.println("success");
} else {
System.out.println("file already exist");
}
}
break;
case "DELETE": {
if (root.deleteFile(content)) {
System.out.println("success");
} else {
System.out.println("no such file");
}
}
break;
default:
break;
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: