文件系统

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.数组
  因为文件树是一个不规则的树,如果用数组实现则会浪费很多空间,当然我们也可以每次给数组重新设定大小,但这样代价太大,所以这里我们代用链表来实现。我们的系统由文件夹和文件组成,所以我们定义如下数据结构
文件
  文件这里用的是一个双向链表,也可以采用单项链表
 1     // 在一个文件夹下的所有文件以链表形式存放
 2     class File {
 3         File pre; // 前一个目录
 4         File next; // 后一个目录
 5         String name; // 目录名称
 6 
 7         public File(String name) {
 8             this.name = name;
 9         }
10     }

文件夹:

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

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

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

  1 import java.util.Scanner;
  2 
  3 public class Main {
  4     static double PI = 3.1415927;
  5 
  6     public static void main(String[] args) {
  7 
  8         FileSystem fileSystem = new FileSystem();
  9         fileSystem.filesystem();
 10     }
 11 }
 12 
 13 class FileSystem {
 14 
 15     // 定义根目录
 16     final static String ROOT = "root";
 17 
 18     // 在同一目录下的所有子目录以链表形式存放
 19     class Dir {
 20         Dir childDir;    // 目录的头结点,头结点为null
 21         Dir pre;         // 前一个目录
 22         Dir next;        // 后一个目录
 23         Dir parent;      // 该目录的父目录
 24         int dirCount;    // 目录个数
 25         String name;     // 目录名称
 26         File file;       // 该文件夹下的文件,以链表形式存放
 27         int fileCount;   // 文件个数
 28 
 29         public Dir(String name) {
 30             this.name = name;
 31             init();
 32         }
 33 
 34         void init() {
 35             file = new File("rootFile");
 36             dirCount = 0;
 37         }
 38 
 39         boolean delete(String dirName) {
 40             if (dirCount == 0) { // 如果当前目录没有子目录,则删除失败
 41                 return false;
 42             }
 43             Dir myhead = childDir; // 从第一目录开始
 44             while (myhead != null) {
 45                 if (myhead.name.equals(dirName)) {
 46 
 47                     if (myhead.dirCount != 0) { // 如果该目录下还有子目录,则删除失败
 48                         return false;
 49                     }
 50                     dirCount--;
 51                     if (myhead.pre != null) {
 52                         myhead.pre.next = myhead.next; // 删除该结点
 53                         myhead.next.pre = myhead.pre;
 54                         myhead = null;
 55                         return true;
 56                     } else {                        //该节点为头结点
 57                         if (myhead.next == null) {
 58                             childDir = null;
 59                         }else {
 60                             childDir = myhead.next;
 61                             childDir.pre = null;
 62                             myhead = null;
 63                         }
 64                         return true;
 65                     }
 66                 }
 67                 myhead = myhead.next; // 依次循环
 68             }
 69             return false;
 70         }
 71 
 72         boolean add(String dirName) {
 73             if (search(dirName) != null) { // 查找该目录文件已经存在
 74                 return false;
 75             }
 76 
 77             Dir dir = new Dir(dirName);
 78 
 79             // 让该目录的子目录都指向自己
 80             dir.parent = this;
 81 
 82             if (dirCount == 0) { // 如果当前目录下没有子目录则,则直接插入
 83                 childDir = dir;
 84                 childDir.next = null;
 85             } else {
 86                 Dir myhead = childDir;
 87                 while (myhead.next != null) {
 88                     myhead = myhead.next;
 89                 }
 90                 myhead.next = dir;
 91                 dir.pre = myhead;
 92                 dir.next = null;
 93             }
 94             dirCount++;
 95             return true;
 96         }
 97 
 98         Dir search(String dirName) { // 查找该目录文件是否存在,存在返回该目录,否则返回null
 99             if (dirCount == 0) {
100                 return null;
101             }
102             Dir myhead = childDir;
103             while (myhead != null) {
104                 if (myhead.name.equals(dirName)) {
105                     return myhead;
106                 }
107                 myhead = myhead.next;
108             }
109             return null;
110         }
111 
112         Dir parent() {
113 
114             // 如果当前目录是根目录,则返回自己
115             if (ROOT.equals(name)) {
116                 return this;
117             }
118             // 如果不是根目录,则返回父目录
119             return parent;
120         }
121 
122         Dir child(String childName) {
123             return search(childName);
124         }
125 
126         boolean deleteFile(String fileName) {
127             if (fileCount == 0) { // 如果当前目录没有子目录,则删除失败
128                 return false;
129             }
130             File myhead = file; // 从第一目录开始
131             while (myhead!= null) {
132                 if (myhead.name.equals(fileName)) {
133                     fileCount--;
134                     if (myhead.pre != null) {
135                         myhead.pre.next = myhead.next; // 删除该结点
136                         myhead.next.pre = myhead.pre;
137                         myhead = null;
138                         return true;
139                     } else {
140                         if (myhead.next==null) {
141                             file = null;
142                         }else {
143                             file = myhead.next;
144                             file.pre = null;
145                             myhead = null;
146                         }
147                         return true;
148                     }
149 
150                 }
151                 myhead = myhead.next; // 依次循环
152             }
153             return false;
154         }
155 
156         boolean addFile(String fileName) {
157             if (searchFile(fileName)) { // 查找该目录文件已经存在
158                 return false;
159             }
160             File newFile = new File(fileName);
161             if (fileCount == 0) { // 如果当前目录下没有子目录则,则直接插入
162                 file = newFile;
163                 file.next = null;
164             } else {
165                 File myhead = file;
166                 while (myhead.next != null) {
167                     myhead = myhead.next;
168                 }
169                 myhead.next = newFile;
170                 newFile.pre = myhead;
171                 newFile.next = null;
172             }
173             fileCount++;
174             return true;
175         }
176 
177         boolean searchFile(String fileName) { // 查找该目录文件是否存在,存在返回true,否则返回false
178             if (fileCount == 0) {
179                 return false;
180             }
181             File myhead = file;
182             while (myhead != null) {
183                 if (myhead.name.equals(fileName)) {
184                     return true;
185                 }
186                 myhead = myhead.next;
187             }
188             return false;
189         }
190     }
191 
192     // 在同一目录下的所有子目录以链表形式存放
193     class File {
194         File pre; // 前一个目录
195         File next; // 后一个目录
196         String name; // 目录名称
197 
198         public File(String name) {
199             this.name = name;
200         }
201     }
202 
203     void filesystem() {
204         Dir root = new Dir(ROOT);
205         Dir rootDir = root;
206         Scanner sc = new Scanner(System.in);
207         while (sc.hasNext()) {
208             String commander = sc.next();
209             String content = sc.next();
210             switch (commander) {
211             case "CD": {
212                 if (content.equals("..")) {
213                     root = root.parent();
214                     System.out.println("success");
215                 } else if (content.equals("\")) {
216                     root = rootDir;
217                     System.out.println("success");
218                 } else {
219                     Dir chlid = root.child(content);
220                     if (chlid == null) {
221                         System.out.println("no such directory");
222                     } else {
223                         root = chlid;
224                         System.out.println("success");
225                     }
226                 }
227             }
228                 break;
229             case "MD": {
230                 if (content.equals("..")) {
231                     System.out.println("directory already exist");
232                 } else {
233                     if (root.add(content)) {
234                         System.out.println("success");
235                     } else {
236                         System.out.println("directory already exist");
237                     }
238                 }
239             }
240                 break;
241             case "RD": {
242                 if (root.delete(content)) {
243                     System.out.println("success");
244                 } else {
245                     System.out.println("can not delete the directory");
246                 }
247             }
248                 break;
249             case "CREATE": {
250                 if (root.addFile(content)) {
251                     System.out.println("success");
252                 } else {
253                     System.out.println("file already exist");
254                 }
255             }
256                 break;
257             case "DELETE": {
258                 if (root.deleteFile(content)) {
259                     System.out.println("success");
260                 } else {
261                     System.out.println("no such file");
262                 }
263             }
264                 break;
265             default:
266                 break;
267             }
268         }
269     }
270 
271 }
原文地址:https://www.cnblogs.com/yfyzy/p/4719608.html