【问题标题】:recursion to iteration递归到迭代
【发布时间】:2012-01-23 19:25:29
【问题描述】:

我正在使用 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();
        }
    }
}

是否可以使用迭代算法来做到这一点?

【问题讨论】:

    标签: java recursion io iteration


    【解决方案1】:

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

    伪代码如下:

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

    【讨论】:

    • @Anouar Elmekki - 为什么要堆叠?队列在这里是完美的。顺便说一句,每个递归函数都可以用栈变成迭代函数,但是太人为了。
    【解决方案2】:

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

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

    -更新

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

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

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

    【讨论】:

      【解决方案3】:

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

      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;
      }
      

      【讨论】:

      • @Petar Minchev 使用堆栈比使用队列(至少是队列的链表实现)运行速度要快一些(~15%)。
      猜你喜欢
      • 2018-06-19
      • 2016-01-05
      • 2013-12-31
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      • 2016-06-14
      相关资源
      最近更新 更多