【问题标题】:Return (not print) all permutations of a string Java返回(不打印)字符串 Java 的所有排列
【发布时间】:2020-07-15 05:09:48
【问题描述】:

关于“查找字符串的排列”有几十个问题,但他们所有的答案都是打印排列。我想创建一个方法,它接受一个输入字符串并返回一个包含所有排列的列表。

这是我的代码:

    public static List<String> allPerms(String str){
        List<String> results = new ArrayList<>();
        while(!allPerms("", str).equals("")) {
            results.add(allPerms("", str));
        }
        
        return results;
    }
    
    private static String allPerms(String perm, String word) {
        if(word.length() == 0)
            return perm;
    
        for(int i = 0; i < word.length(); i++) {
            String small = allPerms(perm + word.charAt(i), word.substring(0, i) + word.substring(i + 1));
            return small;
        }   
    }
    

但这给了我一个错误,说我的私有方法的 for 循环是死代码。有人可以告诉我我在这里做错了什么吗?

【问题讨论】:

  • 一方面,您在循环完成之前返回——只要循环中的第一个allPerms 完成,您就从循环中返回。这使得循环变得不必要。
  • 递归循环。看看这个stackoverflow.com/questions/4795527/…
  • 您应该查看的第一个问题是,您的方法无法编译,因为在所有情况下它都不会返回 String。当你的 for 循环结束时会发生什么?

标签: java string recursion


【解决方案1】:

您的代码存在一些问题,让我们一一解决。函数allPerms(String perm, String word) 包含两个问题:缺少返回语句和 i++ 死代码:

private static String allPerms(String perm, String word) {
    if(word.length() == 0)
         return perm;
    
    for(int i = 0; i < word.length(); i++) { 
        String small = allPerms(perm + word.charAt(i), word.substring(0, i) + word.substring(i + 1));
        return small; // <- if you return here the loop will only iterate once, so i++ is dead code.
    }   
    // <- missing a return statement here
}

我们可以像下面这样修复它:

public static String allPerms(String perm, String word) {
    if(word.length() == 0)
        return perm;
    String small = "";
    for(int i = 0; i < word.length(); i++) {
        small = allPerms(perm + word.charAt(i), word.substring(0, i) + word.substring(i + 1));
    }   
    return small;
}

现在没有编译错误但结果不正确。事实上,如果你运行它,你会得到一个无限循环。原因是因为 allPerms(String str) 方法只有在 allPerms("", str) 方法返回并且空字符串时才会退出 while 循环,而这永远不会是真的! (除非你打电话给allPerms("")


public static List<String> allPerms(String str){
    List<String> results = new ArrayList<>();
    while(!allPerms("", str).equals("")) { // <- infinite loop because never true
        results.add(allPerms("", str));
    }
    
    return results;
}

因此,您需要进行以下更改才能获得排列列表:

public class Main {
    public static List<String> allPerms(String str) {
        return allPerms("", str);
    }
    
    public static List<String> allPerms(String perm, String word) {
        if (word.length() == 0) {
            return Arrays.asList(perm);
        }
        List<String> small = new ArrayList<>();
        for (int i = 0; i < word.length(); i++) {
            small.addAll(allPerms(perm + word.charAt(i), word.substring(0, i) + word.substring(i + 1)));
        }
        return small;
    }

    public static void main(String[] args) {
        System.out.println(allPerms("abc")); // Prints: [abc, acb, bac, bca, cab, cba]
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    相关资源
    最近更新 更多