2017-01-10 3 views
3

私はいくつかの練習問題を実行していますが、そのうちの1つは2つの文字列を取り、私は私の最初の解決策を書いた:2つの文字列が与えられた場合、1が他の文字の部分文字列であるかどうかを再帰的に調べる

public static boolean isSubstring(String s1, String s2){ 
    String longer = s1.length() > s2.length() ? s1 : s2; 
    String shorter = s1.length() < s2.length() ? s1 : s2; 
    String substring; 

    for(int i = 0; i < longer.length() && i + shorter.length() <= longer.length(); i++){ 
     substring = longer.substring(i, i + shorter.length()); 
     if(substring.equals(shorter)) 
      return true; 
    } 
    return false; 
} 

をそして私は、JavaがStringクラスのメソッドが含まれ、その溶液は、その時点で自明である持っていることを思い出しました。 :私が練習していると私は再帰が得意じゃないので

public static boolean isSubstringUsingContains(String s1, String s2){ 
    String longer = s1.length() > s2.length() ? s1 : s2; 
    String shorter = s1.length() < s2.length() ? s1 : s2; 
    return longer.contains(shorter); 

} 

、私は再帰的にこの問題を解決するために試してみてくださいと思った、と私は正確にそうすることができていません。再帰でこれをどのように解決できますか?また、上記の解法とは対照的に、ここで再帰を使用するための長所と短所があります。ここでは、この問題のための再帰的な解決策で私の失敗した試みです:

public static boolean isSubstringRecursive(String s1, String s2,int i){ 
    if(s1.length() == 0 || s2.length() == 0) 
    return false; 

    String longer = s1.length() > s2.length() ? s1 : s2; 
    String shorter = s1.length() < s2.length() ? s1 : s2; 

    if(longer.equals(shorter)) 
    return true; 

    return isSubstringRecursive(longer.substring(i,i + shorter.length()),shorter,i + 1); 


} 

EDIT

テストケース: 文字列A = "バットマン" 文字列B = "気圧" RESULT:真の

文字列A = "逆立ち" 文字列B = RESULT "スタンド":真の

を文字列A = "Hotsauce" 文字列B = "ECU" 結果:偽

+0

あなたはテストケースを持っていますか? –

+3

再帰はdiguiseのループです - 作業コードにループはありません:なぜ再帰が必要だと思いますか? – assylias

+1

あなたの基本ケースには 'startsWith'を、再帰的には' substring(1) 'を使うことをお勧めします。長い文字列が短い文字列で始まる場合は、終了します。それ以外の場合は、最初の文字を消して再帰します。 –

答えて

1

私はそれを機能させるためにあなたのルーチンに最小限の変更を加えています。説明のためにコード内の私のコメントを見てください。

/* Adding an extra argument to store the longest value constantly across multiple recursions. */ 
public static boolean isSubstringRecursive(String longString, String s1, String s2,int i){ 

    if(s1.length() == 0 || s2.length() == 0) 
    return false; 

    String longer = s1.length() >= s2.length() ? s1 : s2; 
    String shorter = s1.length() < s2.length() ? s1 : s2; 

    /* set the longString in the first iteration only */ 
    if(i==0)longString=longer; 

    if(longer.equals(shorter)) 
    return true; 

    /* To prevent substring to go out of boounds */ 
    if(i+ shorter.length() > longString.length()) return false; 

    /* Use longString for substring since it holds the originally long string */ 
    return isSubstringRecursive(longString, longString.substring(i,i + shorter.length()),shorter,i + 1); 

} 

このコードは、さらに高度に最適化することができます。しかし、私はさらなる仕事のためにあなたにその部分を残します。

注1::これは、Stringクラスの 'contains'メソッドを使用して簡単に実現できます。ただし、containsでデモしたソリューションでは、実際に文字列の長さを確認する必要はありません。以下を参照してください:2

return s1.contains(s2) || s2.contains(s1);

注:また、同じことを行うために、StringクラスのindexOfを使用することができます。以下を参照してください:

return (s1.indexOf(s2) != -1 || s2.indexOf(s1) != -1);

かいつまんで、recursionオプションのために行く必要がないことをあなたの目的を達成するために非常に多くのより容易な選択肢があります。

+0

ありがとうございました。私は再帰で正しい道のどこかにいたことが良いと感じています。私はそれがこのような問題のために不必要であることに同意するが、私のスキルを向上させるために時間を割いてくれてありがとう。 –

関連する問題