web-dev-qa-db-ja.com

Javaでの再帰による文字列の反転

以下に、文字列を再帰的に逆にするコードJavaを示します。

誰かがそれがどのように機能するかの説明を提供できますか?

public static String reverse(String str) {
    if ((null == str) || (str.length() <= 1)) {
        return str;
    }
    return reverse(str.substring(1)) + str.charAt(0);
}

これがどのように機能するのか理解していない。

47
Bob Sanders

この関数は、文字列の最初の文字を取得します-str.charAt(0)-末尾に配置し、それ自体を呼び出します-reverse()-残りの部分でstr.substring(1)、これらを追加します結果を得るための2つのこと-reverse(str.substring(1)) + str.charAt(0)

渡されたStringが1文字以下で、残りが残っていない場合-str.length() <= 1)の場合-再帰的に呼び出しを停止し、渡されたStringを返します。

したがって、次のように実行されます。

reverse("Hello")
(reverse("Ello")) + "H"
((reverse("llo")) + "e") + "H"
(((reverse("lo")) + "l") + "e") + "H"
((((reverse("o")) + "l") + "l") + "e") + "H"
(((("o") + "l") + "l") + "e") + "H"
"olleH"
93
Dave Webb

one呼び出しだけではなく、nested呼び出しがあることを覚えておく必要があります。そのため、「最も高度にネストされた」呼び出しがすぐに戻るとき(「o」が見つかったとき)、次のレベルはstr.charAt(0)を取ります-strはその時点で「lo」です。そのため、「ol」が返されます。

次に、nextレベルは「ol」を受け取り、itsstrの値(「llo」)に対してstr.charAt(0)を実行し、「oll」を次のレベル。

次に、nextレベルは再帰呼び出しから「oll」を受け取り、itsstrの値(「Ello」)に対してstr.charAt(0)を実行し、次のレベルに「olle」。

次に、finalレベルは、再帰呼び出しから「oll」を受け取り、itsstrの値(「hello」)に対してstr.charAt(0)を実行し、元の発信者への「olleh」。

あなたが行くようにスタックを考えることは理にかなっているかもしれません:

// Most deeply nested call first...
reverse("o") -> returns "o"
reverse("lo") -> adds 'l', returns "ol" 
reverse("llo") -> adds 'l', returns "oll" 
reverse("Ello") -> adds 'e', returns "olle" 
reverse("hello") -> adds 'h', returns "olleh" 
20
Jon Skeet

デバッガーで実行します。すべてが明らかになります。

4
Dave

これは再帰的であるため、各ステップでの出力は次のようになります。

  1. 「こんにちは」と入力します。次に、メソッドは「Ello」で自身を呼び出し、結果+「H」を返します。
  2. 「Ello」と入力します。メソッドは「llo」で自身を呼び出し、結果+「e」を返します
  3. 「llo」が入力されます。メソッドは自身を「lo」で呼び出し、結果+「l」を返します
  4. 「lo」が入力されます。メソッドは自身を「o」で呼び出し、結果+「l」を返します
  5. 「o」が入力されます。メソッドはif条件をヒットし、「o」を返します

結果を見てみましょう:

合計戻り値は、再帰呼び出しの結果と最初の文字を提供します

5からの戻り値: "o"

4からの戻り値は、「o」+「l」です。

3からの戻り値は、「ol」+「l」になります。

2からの戻り値は、「oll」+「e」です。

1からの戻り値は、「olle」+「H」です。

これにより、「olleH」の結果が得られます

2
jzworkman

以下のコードを実行します-印刷されます:

ステップ0:Ello/H
ステップ1:llo/e
ステップ2:lo/l
ステップ3:o/l
ステップ3からの戻り:ol
ステップ2が戻ります:oll
ステップ1が戻ります:olle
ステップ0の戻り値:olleH

コード:

public class Test {

    private static int i = 0;

    public static void main(String args[]) {
        reverse("Hello");
    }

    public static String reverse(String str) {
        int localI = i++;
        if ((null == str) || (str.length()  <= 1)) {
            return str;
        }
        System.out.println("Step " + localI + ": " + str.substring(1) + " / " + str.charAt(0));
        String reversed = reverse(str.substring(1)) + str.charAt(0);

        System.out.println("Step " + localI + " returns: " + reversed);
        return reversed;
    }
}
2
assylias

インラインサンプル。

public static String strrev(String str) {
    return !str.equals("") ? strrev(str.substring(1)) + str.charAt(0) : str;
}

以下を実行すると、何が起こっているのかがわかります。

public class RS {

    public static String reverse(String str) {
        System.out.println("--- reverse --- " + str);
        if ((null == str) || (str.length() <= 1)) {
            return str;
        }
        return add(reverse(str.substring(1)), charAt(str));
    }

    public static char charAt(String s) {
        System.out.println("--- charAt --- " + s);
        return s.charAt(0);
    }

    public static String add(String s, char c) {
        System.out.println("--- add --- " + s + " - " + c);
        return s + c;
    }

    public static void main(String[] args) {
        System.out.println("start");
        System.out.println("result: " + reverse("hello"));
        System.out.println("end");
    }

}
0
Tom

私の知る限り、すべての再帰関数には2つのことがあります。

  1. 停止条件が常にあります。

    if((null == str)||(str.length()<= 1)){return str; }

  2. 再帰はstackメモリを使用します。これは[〜#〜] lifo [〜#〜]メカニズムを使用するため、復帰が発生します。

0
Chulo

私が見つけたベストソリューション。

public class Manager
{
    public static void main(String[] args)
    {
        System.out.println("Sameer after reverse : " 
                         + Manager.reverse("Sameer"));
        System.out.println("Single Character a after reverse : " 
                         + Manager.reverse("a"));
        System.out.println("Null Value after reverse : "
                         + Manager.reverse(null));
        System.out.println("Rahul after reverse : "
                         + Manager.reverse("Rahul"));
    }

    public static String reverse(String args)
    {
        if(args == null || args.length() < 1 
                                || args.length() == 1)
        {
            return args;
        }
        else
        {
                return "" + 
                               args.charAt(args.length()-1) + 
                               reverse(args.substring(0, args.length()-1));                                  
        }
    }
}

出力:C:\ Users\admin\Desktop> Java Managerリバース後の同じ:reemaSリバース後の単一文字:リバース後のNULL値:ヌル後のRahulリバース後:luhaR

0
Vicky K
import Java.util.*;

public class StringReverser
{
   static Scanner keyboard = new Scanner(System.in);

   public static String getReverser(String in, int i)
   {
      if (i < 0)
         return "";
      else
         return in.charAt(i) + getReverser(in, i-1);
   }

   public static void main (String[] args)
   {
      int index = 0;

      System.out.println("Enter a String");
      String input = keyboard.nextLine();


      System.out.println(getReverser(input, input.length()-1));
   }
}
0
Chris Zog

Javaで文字列を反転する別のソリューション。

.toCharArray()関数を使用して、文字列をchar配列に変換します。

public static char[] reverse(char in[], int inLength, char out[],
            int tractOut) {

        if (inLength >= 0) {
            out[tractOut] = in[inLength];
            reverse(in, inLength - 1, out, tractOut + 1);
        }

        return null;

    }
0
public class ReverseString{

private static  String reverse(String text, String reverseStr){
    if(text == null || text.length() == 0){
        return reverseStr;
    }
    return reverse(text.substring(1), text.charAt(0)+reverseStr);
}
public static void main(String [] args){
    System.out.println(reverse("hello", "")); //output is "olleh"
}

}

0
Venkata Buchi
class Test {
   public static void main (String[] args){
      String input = "hello";
      System.out.println(reverse(input));
    }

    private static String reverse(String input) {
        if(input.equals("") || input == null) {
        return "";
    }
    return input.substring(input.length()-1) + reverse(input.substring(0, input.length()-1));
} }

サンプルコードスニペットを以下に示します。これが役立つ場合があります。私のために働いた。

0
Kaustubh

文字列Helloを取得し、再帰的に実行します。

したがって、最初の呼び出しは以下を返します:

return reverse(Ello) + H

第二

return reverse(llo) + e

最終的にolleHを返します

0
len

Reverce(substring(1))の呼び出しは、charAt(0)を追加する前に実行されます。呼び出しはネストされているため、サブ文字列の逆が呼び出されてから、2番目の文字(サブ文字列であるため新しい最初の文字)が追加されます。

reverse( "Ello")+ "H" = "olleH"
-------- ^ -------
reverse( "llo")+ "e" = "olle"
--------- ^ -----
reverse( "lo")+ "l" = "oll"
-------- ^ -----
reverse( "o")+ "l" = "ol"
--------- ^ ----
"o" = "o"

0
PATRY Guillaume