Java - 使用递归从字符串创建所有子字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18280442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:00:30  来源:igfitidea点击:

Java - using recursion to create all substrings from a string

javarecursion

提问by davidjhp

The following code in Java uses recursion to create all possible substrings from a string. I am wondering is there a better way of coding this? I want to use recursion.

以下 Java 代码使用递归从字符串创建所有可能的子字符串。我想知道有没有更好的编码方法?我想使用递归。

public class main {

    public static void main(String[] args) {
        generate("hello");
    }

    public static void generate(String word) {
        if (word.length() == 1) {
            System.out.println(word);
            return;
        }else{
            System.out.println(word);
            generate(word.substring(0, word.length()-1)); 
            generate(word.substring(1, word.length())); 
        }

    }

}

FAQ Q - Why do I want to do this using recursion? A - Because the CEO of StackOverflow says recursion is important http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html

常见问题 Q - 为什么我要使用递归来做到这一点?A - 因为 StackOverflow 的 CEO 说递归很重要 http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html

采纳答案by davidjhp

The following turned out to be the best solution:

事实证明,以下是最好的解决方案:

public class recursive {

    static String in = "1234";

    public static void main(String[] args) {
        substrings(0,1);
    }

    static void substrings(int start, int end){
        if(start == in.length() && end == in.length()){
            return;
        }else{
            if(end == in.length()+1){
                substrings(start+1,start+1);
            }else{
                System.out.println(in.substring(start, end));
                substrings(start, end+1);
            }
        }
    }

}

It first checks the base case: if both start and end are equal to in.length(). Because if they are, that means there are no more substrings to be found, and the program ends.

它首先检查基本情况:如果开始和结束都等于 in.length()。因为如果它们是,那就意味着没有更多的子串可以找到,程序就结束了。

Let's start with start=0 and end=1. They obviously don't equal in.length(), and end definitely doesn't equal in.length()+1. Thus, substring(0,1) will be printed out, which is 1. The next iteration of substrings will be substrings(0,2), and in.substring(0,2) will be printed, which is 12. This will continue until end == in.length()+1, which happens when the program finishes substrings(0,4) and tries to move on to substrings(0,5). 5 == in.length()+1, so when that happens, the program will do substrings(start+1,start+1), which is substrings(1,1). The process will continue with substrings(1,2), and (1,3), until (1,5) when the program will run substrings(2,2).

让我们从 start=0 和 end=1 开始。它们显然不等于 in.length(),并且 end 绝对不等于 in.length()+1。因此,将打印出 substring(0,1),即 1。子串的下一次迭代将是 substrings(0,2),并且将打印 in.substring(0,2),即 12。这将继续直到 end == in.length()+1,当程序完成 substrings(0,4) 并尝试移动到 substrings(0,5) 时会发生这种情况。5 == in.length()+1,所以当这种情况发生时,程序会做 substrings(start+1,start+1),也就是 substrings(1,1)。该过程将继续使用 substrings(1,2) 和 (1,3),直到程序运行 substrings(2,2) 直到 (1,5)。

All of this will continue until substrings(4,4), which, at that point, the program stops.

所有这一切都将继续,直到 substrings(4,4),此时程序停止。

The result looks like this:

结果如下所示:

1 12 123 1234

1 12 123 1234

2 23 234

2 23 234

3 34

3 34

4

4

回答by Honza Brabec

This problem has overlapping subproblems and because of that the top-down recursion as you do is not much effective. You are evaluating multiple substrings multiple times.

这个问题有重叠的子问题,因为你所做的自上而下的递归并不是很有效。您正在多次评估多个子字符串。

Actually it is horribly ineffective (I would guess O(2^n)). Just try to run it on a bit longer string.

实际上它是非常无效的(我猜是 O(2^n))。尝试在更长的字符串上运行它。

generate("OverlappingSubproblems");

If you are interested in a better way of solving this you can try something like this:

如果您对解决此问题的更好方法感兴趣,可以尝试以下操作:

public static void generate2(String word) {
    for (int from = 0; from < word.length(); from++) {
        for (int to = from + 1; to <= word.length(); to++) {
            System.out.println(word.substring(from, to));
        }
    }
}

If you want to use recursion you can try to rewrite the for-loops with recursion as exercise ;)

如果你想使用递归,你可以尝试用递归重写for循环作为练习;)

回答by Jason C

There is a lot to be learned from Honza's answer.I suggest you try and rewrite that as a recursive algorithm.

从 Honza 的回答中可以学到很多东西。我建议您尝试将其重写为递归算法。

As with any recursive approach, divide it into self-referencing subproblems:

与任何递归方法一样,将其划分为自引用子问题:

1. substrings(X) = substrings_starting_at_first_character(X) + substrings(X minus first char).
2. substrings_starting_at_first_character(X) = X + substrings_starting_at_first_character(X minus last char).

Next figure out your non-self-referencing base cases:

接下来找出您的非自引用基本情况:

1. substrings("") = empty set.
2. substrings_starting_at_first_character("") = empty set.

And go from there.

从那里去。

回答by Anshu

Another clean approach - using both looping and recursion (and does not have overlapping problem)

另一种干净的方法 - 使用循环和递归(并且没有重叠问题)

public static void printCombinations(String initial, String combined) {
    System.out.print(combined + " ");
    for (int i = 0; i < initial.length(); i++) {
        printCombinations(initial.substring(i + 1),
                combined + initial.charAt(i));

    }
}


public static void main(String[] args) {
        printCombinations("12345", "");
    }

And output is - 1 12 123 1234 12345 1235 124 1245 125 13 134 1345 135 14 145 15 2 23 234 2345 235 24 245 25 3 34 345 35 4 45 5

并且输出是 - 1 12 123 1234 12345 1235 124 1245 125 13 134 1345 135 14 145 15 2 23 234 2345 235 24 245 3 5 3 4 3

回答by SK1

 //substring all the words from a string
  public class RecSubstring
  {
    static int c=0; 
    static void rec(String str)
    {
      if(str.equals(""))
        return;
      else
      {
        c=str.indexOf(' ');  
        System.out.println(str.substring(0,c));
        rec(str.substring(c+1));
     }
   }

  public static void main(String args[])
  {
    String st="We are Happy"+" " ;
    rec(st);
  }
 }

回答by Ashwini Kumar Maurya

public class SubsequencesOfStr {

 public static void main(String[] args) {

  String str = "abcd";
  System.out.println("0000----" + str.length());
  linearCombination(str);
 }

 static void linearCombination(String str) {
  for (int i = 0; i < str.length(); i++) {
   int endIndex = i + 1;
   for (int j = 0; j < str.length() - i; j++) {
    System.out.println(str.substring(j, endIndex));
    endIndex++;
   }
  }
 }
}