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 问 - 为什么我要使用递归来做这个? 答:因为StackOverflow的首席执行官表示递归非常重要 http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
答案 0 :(得分:15)
这个问题有重叠的子问题,因为你做的那样自上而下的递归并不是很有效。您正在多次评估多个子字符串。
实际上它非常无效(我猜是O(2 ^ n))。只是尝试在更长的字符串上运行它。
generate("OverlappingSubproblems");
如果您对解决此问题的更好方法感兴趣,可以尝试以下方法:
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));
}
}
}
如果你想使用递归,你可以尝试用递归重写for循环作为练习;)
答案 1 :(得分:6)
以下证明是最佳解决方案:
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);
}
}
}
}
它首先检查基本情况:如果start和end都等于in.length()。 因为如果它们是,那意味着没有更多的子串可以找到,并且程序结束。
让我们从start = 0和end = 1开始。它们显然不等于in.length(),并且end绝对不等于in.length()+ 1。 因此,子串(0,1)将被打印出来,即1。 子串的下一次迭代将是子串(0,2),并且将打印in.substring(0,2),这将是12.这将持续到end == in.length()+ 1,这发生在程序完成子串(0,4)并尝试继续子串(0,5)。 5 == in.length()+ 1,所以当发生这种情况时,程序将执行子串(start + 1,start + 1),这是子串(1,1)。当程序运行子串(2,2)时,该过程将继续使用子串(1,2)和(1,3),直到(1,5)。
所有这一切都将持续到子串(4,4),此时程序停止。
结果如下:
1 12 123 1234
2 23 234
3 34
4
答案 2 :(得分:1)
从Honza的答案中可以学到很多东西。我建议你尝试将其重写为递归算法。
与任何递归方法一样,将其划分为自引用子问题:
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).
接下来找出你的非自引用基本情况:
1. substrings("") = empty set.
2. substrings_starting_at_first_character("") = empty set.
从那里开始。
答案 3 :(得分:0)
另一种干净的方法 - 使用循环和递归(并且没有重叠问题)
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", "");
}
输出为 - 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
答案 4 :(得分:0)
//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);
}
}
答案 5 :(得分:0)
Pin
答案 6 :(得分:0)
void allsubstring(string s,int start,int end)
{
if(start == s.size() && end == s.size()) {
return;
}
else {
if(end == s.size()) {
allsubstring(s,start+1,start+1);
}
else {
cout<<s.substr(start,end-start+1)<<endl;
allsubstring(s,start,end+1);
}
}
}
答案 7 :(得分:0)
另一种使用递归的方法
public static void main(String[] args)
{
subStrings("ABCDE");
}
static void subStrings(String str)
{
if(str.length()==0)
{
return;
}
subString(str);
subStrings(str.substring(1,str.length()));
}
private static void subString(String str)
{
if(str.length()==1)
{
System.out.print(str+" ");
return;
}
System.out.print(str+" ");
subString(str.substring(0,str.length()-1));
}
答案 8 :(得分:0)
这是我使用 2 个递归函数 pss 和 pss1 分别模拟标准 O(n^2) 解决方案的外部和内部 for 循环的方法。只有这一次,递归?。
abc 的输出:a,ab,abc,b,bc,c
// print substrings using recursion
void pss1 ( string s , int i , string op)
{
// pss1 prints all substrings from a given index
if(i==s.length()-1)
{
op+=s[i];
cout<<op<<endl;
return;
}
op+=s[i];
cout<<op<<endl;
pss1(s,i+1,op);
}
void pss ( string s , int i , string op)
{
// pss repeats the process of pss1 for all indices by reducing the string size by 1 each time from the front (i.e) abc becomes bc at the 2nd call of psss
if(s.length()==1)
{
cout<<s<<endl;
return;
}
else
{
pss1(s,0,op);
string S=s.substr(1);
pss(S,0,"");
}
return ;
}
int main()
{
string s;
cin>>s;
pss(s,0,"");
return 0;
}
答案 9 :(得分:0)
这是仅使用 1 个递归函数的工作代码。
@davidjhp 的解决方案在 C++ 中的实现
分析递归问题中的递归堆栈图,以了解如何针对较小的问题解决给定问题以产生最终解决方案。
df$outcome <- sapply(df$location, systemFail)