TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
给定一个目录,打印出该目录包含的目录或者文件的结构来,文件和其父目录之间通过缩进来表示父子关系。
比如:
0 Test$
--1 src$
----2 TravelDir.java
----2 pms$
0 Test$ --1 src$ ----2 TravelDir.java ----2 pms$ --1 bin$ 表示Test目录下有两个目录:src和bin,src目录里有一个文件TravelDir.java和一个目录pms。(目录名字后面带$,文件不带)
其实遍历打印目录结构,就是对目录这个”树结构“进行遍历,按照上述结构的话,应该是采用深度优先遍历。
为了完成对特定文件名字的筛选,首先定义一个文件名字过滤接口:(策略模式?O(∩_∩)O)
FileNameFilter
- [/code]
-
-
- 1
- interface
- FileNameFilter{
-
- 2
-
- boolean
- accept(String filename);
-
- 3
- }
-
-
-
- 1)采用递归实现
-
- [img]http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/【JAVA】遍历打印目录结构[/img]
- 代码
-
-
-
- 1
- /*
-
-
- 2
- * 参数:root:要遍历的文件,
-
- 3
- *spanToLeft:距离左边的空白或者分隔符数目,
-
- 4
- *spanChar:空白字符,
-
- 5
- *filter:根据条件选择文件
-
- 6
- *
-
- 7
-
- */
-
-
- 8
-
- private
-
- void
- travel(File root,
- int
- spanToLeft,
- char
- spanChar,
-
- 9
- FileNameFilter filter) {
-
- 10
- spanToLeft
- +=
-
- 4
- ;
-
- 11
-
- if
- (root.isFile()) {
-
- 12
- String name
- =
- root.getName();
-
- 13
-
- if
- (filter.accept(name)) {
-
- 14
-
- for
- (
- int
- k
- =
-
- 0
- ; k
- <
- spanToLeft; k
- ++
- ) {
-
- 15
- strDir.append(spanChar);
-
- 16
- }
-
- 17
- strDir.append(root.getName()
- +
-
- "
-
- "
- );
-
- 18
- fileCount
- ++
- ;
-
- 19
- }
-
- 20
- }
- else
-
- if
- (root.isDirectory()) {
-
- 21
-
- for
- (
- int
- k
- =
-
- 0
- ; k
- <
- spanToLeft; k
- ++
- ) {
-
- 22
- strDir.append(spanChar);
-
- 23
- }
-
- 24
- strDir.append(root.getName()
- +
-
- "
- $
- "
- );
-
- 25
- dirCount
- ++
- ;
-
- 26
- File[] children
- =
- root.listFiles();
-
- 27
-
- if
- (children
- ==
-
- null
- )
-
- 28
-
- return
- ;
-
- 29
-
- for
- (
- int
- i
- =
-
- 0
- ; i
- <
- children.length; i
- ++
- ) {
-
- 30
- travel(children[i], spanToLeft, spanChar, filter);
-
- 31
- }
-
- 32
- }
-
- 33
- }
-
- 34
-
-
- 35
-
- public
-
- void
- travelDir(File root,
- int
- spanToLeft,
- char
- spanChar,
-
- 36
- FileNameFilter filter){
-
- 37
-
- if
- (root
- ==
-
- null
- )
-
- 38
-
- return
- ;
-
- 39
-
- if
- (
- !
- root.exists()) {
-
- 40
- System.err.println(
- "
- file
- "
-
- +
- root.getName()
- +
-
- "
- does not exist!
- "
- );
-
- 41
-
- return
- ;
-
- 42
- }
-
- 43
- travel(root, spanToLeft, spanChar, filter);
-
- 44
-
-
-
-
-
- 45 }
- 2)采用非递归实现(用堆栈)
-
- 为了保存每个文件的层次信息,定义一个类,保存文件名和层次信息
-
-
- [img]http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/【JAVA】遍历打印目录结构[/img]
- FileDesc
-
-
-
- 1
- class
- FileDesc {
-
- 2
-
- public
- String filename;
-
- 3
-
- public
-
- int
- fileindex;
-
- 4
-
-
- 5
-
- public
- FileDesc(String name,
- int
- index) {
-
- 6
- filename
- =
- name;
-
- 7
- fileindex
- =
- index;
-
- 8
- }
-
-
-
-
- 9 }
- 非递归代码:
-
- [img]http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/http://www.java3z.com/cwbwebhome/article/article2/【JAVA】遍历打印目录结构[/img]
- 非递归代码
-
-
-
- 1
- public
- ArrayList
- <
- FileDesc
- >
- travelWithStack(File root, FileNameFilter filter) {
-
- 2
- ArrayList
- <
- FileDesc
- >
- res
- =
-
- new
- ArrayList
- <
- FileDesc
- >
- ();
-
- 3
-
- if
- (root
- ==
-
- null
- )
-
- 4
-
- return
- res;
-
- 5
- Stack
- <
- File
- >
- stack
- =
-
- new
- Stack
- <
- File
- >
- ();
-
- 6
- Stack
- <
- Integer
- >
- stack1
- =
-
- new
- Stack
- <
- Integer
- >
- ();
-
- 7
- stack.push(root);
-
- 8
- stack1.add(
- 0
- );
-
- 9
-
- while
- (
- !
- stack.empty()) {
-
- 10
- File file
- =
- stack.pop();
-
- 11
-
- int
- iii
- =
- stack1.pop();
-
- 12
-
- if
- (file.isDirectory()) {
-
- 13
- FileDesc desc
- =
-
- new
- FileDesc(file.getName()
- +
-
- "
- $
- "
- , iii);
-
- 14
- res.add(desc);
-
- 15
- dirCount
- ++
- ;
-
- 16
- File[] children
- =
- file.listFiles();
-
- 17
-
- if
- (children
- ==
-
- null
- )
-
- 18
-
- continue
- ;
-
- 19
-
- for
- (
- int
- i
- =
-
- 0
- ; i
- <
- children.length; i
- ++
- ) {
-
- 20
- stack.push(children[i]);
-
- 21
- stack1.push(iii
- +
-
- 1
- );
-
- 22
- }
-
- 23
- }
- else
-
- if
- (file.isFile()) {
-
- 24
- String filename
- =
- file.getName();
-
- 25
-
- if
- (filter.accept(filename)) {
-
- 26
- FileDesc desc
- =
-
- new
- FileDesc(filename, iii);
-
- 27
- res.add(desc);
-
- 28
- fileCount
- ++
- ;
-
- 29
- }
-
- 30
- }
-
- 31
- }
-
- 32
-
- return
- res;
-
-
-
-
- 33 }
- 当初学数据结构的时候,学到树遍历那一章,感觉用递归实现遍历,无论是深度优先还是广度优先(注:转成非递归,深度优先用堆栈,广度优先用队列),代码都比较简单而且容易理解。那时候听说非递归实现很难实现,因此连敢看都没敢看,其实那本书也提供了伪代码。但当时感觉还是不怎么明白,也没怎么仔细看。所以一直以来觉得递归转非递归很难,而且也没怎么实际写过代码。前段时间去参加一个单位的笔试题,里面就有一道题要求用非递归实现二叉树的先序遍历,呵呵,说实话,以前还真没怎么写过,都是用递归。于是在考场时试着写了一下,没想到仔细理了一下思路,很快就写出来了,其实没想象中那么难。最近也在研究了一下算法,感觉还是很有意思的,以前总觉得算法很深奥,其实现在想想,没那么高深,关键不能只是在想,要亲自去试试。
-
- ps:也许很多事情没我们想象的那么复杂,亲自去尝试一下,你不去尝试怎么知道自己不行呢。。。
-
-
-
-
- 其实写这个程序主要有一个目的,就是想统计一下我电脑里的音乐文件夹下面的音乐文件。
-
-
-
- 以下是我用程序输出的结果(直接输出到文件里):
-
-
- [url=http://files.cnblogs.com/gaojing/travelDir-output.rar]点击下载[/url]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [code]
复制代码 |
|