递归到迭代

时间:2011-12-19 17:39:17

标签: java recursion io iteration

我正在使用Java的Windows桌面应用程序中工作。在我的应用程序中,需要搜索所有.php。为此,我使用递归方法。

import java.io.File;

public class Copier {

    public static void find(String source,String rep) {
        File src = new File(rep);
        if (src!= null && src.exists() && src.isDirectory()) {
            String[] tab = src.list();
            if (tab != null) {
                for(String s : tab) {
                    File srcc = new File(rep+"\\"+s);
                    if (srcc.isFile()) {  
                        if (srcc.getName().matches(".*"+source+"$")) {
                            System.out.println(s);
                        }
                    } else {
                        find(source,srcc.getAbsolutePath());
                    }
                }
            } else {
                //System.out.println(" list is null");
            }
        }
    }

    public static void main(String[] args) {
        try {
            find(".java", "C:\\");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

是否可以使用迭代算法执行此操作?

3 个答案:

答案 0 :(得分:3)

当然。将breadth-first-search与队列一起使用。从C:\开始,每次从队列中弹出顶层文件夹,并将所有子文件夹推送到队列末尾。

伪代码如下:

queue.push("C:\");
while (!queue.empty()) { 
   String topFolder = queue.pop();
   foreach (subFolder of topFolder) {
        queue.push(subFolder);
   }
}

答案 1 :(得分:1)

我不明白你为什么要摆脱递归,虽然理论上你正在寻找的东西是可能的。

但是,获得更快程序的好方法可能是在列出目录的子项时使用filefilter。一个用于目录,一个用于匹配文件(这个应该使用java.util.regexp.Pattern)。

- 更新

您可以找到File.list重载的文档以使用here。对于模式,您可能会像局部变量(在循环外部或数据成员,如果您使用递归)。

 Pattern p = Pattern.compile( ".*"+source+".*" );
 boolean found = p.matcher( p.matcher( srcc.getName() ).matches() );

哦,顺便说一句,不要将srcc转换成文件!使用字符串并尽可能少地构建对象。

答案 2 :(得分:1)

您始终可以使用队列代替递归。在这种情况下,我认为它使代码看起来更容易阅读。通常,你会从迭代实现中获得比递归更好的性能,但在这种情况下,它们都以几乎相同的速度运行(至少在我的机器上)。

public static List<String> find(final String source, final String directory)
{
    List<String> results = new LinkedList<String>();
    Stack<String> stack = new Stack<String>();

    stack.add(directory);

    String rep;
    while (!stack.isEmpty()) {
        rep = stack.pop();
        File src = new File(rep);
        if (src != null && src.exists() && src.isDirectory()) {
            String[] tab = src.list();
            if (tab != null) {
                for (String s : tab) {
                    File srcc = new File(rep + File.separatorChar + s);
                    if (srcc.isFile()) {
                        if (srcc.getName().matches(".*" + source + "$")) {
                            // System.out.println(s);
                            results.add(s);
                        }
                    } else {
                        stack.add(srcc.getAbsolutePath());
                    }
                }
            } else {
                // System.out.println(" list is null");
            }
        }
    }
    return results;
}