在 Java 中使用递归反转字符串

Posted

技术标签:

【中文标题】在 Java 中使用递归反转字符串【英文标题】:Reversing a String with Recursion in Java 【发布时间】:2012-04-01 04:59:19 【问题描述】:

下面是一些递归反转字符串的 Java 代码。

有人能解释一下它是如何工作的吗?

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

我不明白这怎么可能工作。

【问题讨论】:

这是作业,@DwB - 我认为这是递归的合理演示。 @DwB 它有一个作业标签,所以他们可能正在使用它来教授递归。它是第一次了解递归如何工作的最简单方法之一 我加评论的时候没有homework标签。 @DwB 对不起,DwB,你是对的,我上面没有作业标签。这不一定适用于现实世界的应用程序,只是为了让我了解这个递归示例中到底发生了什么。 我今天被问到这个问题,我想我应该想出你写的东西。我确实想出了这个pastebin.com/r4B3xEMe 更多代码,但在一半的调用中反转。 【参考方案1】:

通过调试器运行它。一切都会变得清晰。

【讨论】:

“到目前为止,最好的答案”?那么为什么会变成0呢?为什么人们一直说要看它在这么长的弦上运行?在什么情况下它会在“null==str”处终止?即使是新创建的 String 对象也不会这样做。毕竟,空字符串对象的长度是多少?【参考方案2】:

您需要记住,您不会只有 一个 调用 - 您将有 嵌套 调用。因此,当“最高度嵌套”的调用立即返回时(当它只找到“o”时),下一级将采用str.charAt(0) - 其中str 是“lo”。所以这将返回“ol”。

然后下一个关卡将接收到“ol”,执行str.charAt(0) for 值为str(即“llo”),返回“oll”到一个新的水平。

然后 next 级别将从其递归调用中接收“oll”,执行 str.charAt(0) 以获取 值为 str(即“ello”) ,将“olle”返回到下一个级别。

然后 final 级别将从其递归调用中接收“oll”,执行 str.charAt(0) 以获取 值为 str(即“hello”) ,将“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" 

【讨论】:

我认为这是正确的简单解释,而不是被接受的解释,因为递归调用将首先被评估,然后是“str.charAt(0)”。将最后一行分成两行“String ab = reverse(str.substring(1)); return ab + str.charAt(0);”会更好地理解【参考方案3】:

该函数获取字符串的第一个字符 - str.charAt(0) - 将其放在末尾,然后调用自身 - reverse() - 在其余部分 - str.substring(1),将这两件事加在一起得到结果 - @ 987654324@

当传入的 String 是一个字符或更少时,将不会有余数 - 当 str.length() &lt;= 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"

【讨论】:

【参考方案4】:

因为这是递归的,所以每一步的输出都会是这样的:

    输入“你好”。然后该方法使用“ello”调用自身,并将返回结果 +“H” 输入“你好”。该方法使用“llo”调用自身,并将返回结果+“e” 输入“llo”。该方法使用“lo”调用自身,并将返回结果+“l” 输入“lo”。该方法使用“o”调用自身,并将返回结果+“l” 输入“o”。该方法将满足 if 条件并返回“o”

现在来看结果:

总返回值会给你递归调用的结果加上第一个字符

从5返回将是:“o”

4 的返回值将是:“o”+“l”

3 的返回值是:"ol" + "l"

2 的返回值是:"oll" + "e"

从 1 返回的结果是:"olle" + "H"

这会给你“olleH”的结果

【讨论】:

【参考方案5】:

获取字符串 Hello 并递归运行它。

所以第一次调用会返回:

return reverse(ello) + H

第二

return reverse(llo) + e

最终会返回olleH

【讨论】:

【参考方案6】:

对 reverce(substring(1)) 的调用将在添加 charAt(0) 之前执行。 由于调用是嵌套的,因此在添加前第二个字符(新的第一个字符,因为这是子字符串)之前,将调用子字符串上的反转

反向 ("ello") + "H" = "olleH" --------^------- 反向(“llo”)+“e”=“olle” ---------^----- 反向(“lo”)+“l”=“oll” --------^----- 反向(“o”)+“l”=“ol” ---------^---- "o" = "o"

【讨论】:

【参考方案7】:

运行下面的代码 - 它会打印:

第 0 步:hello / 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;
    

【讨论】:

【参考方案8】:

运行以下命令,你会看到发生了什么:

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");
    


【讨论】:

【参考方案9】:

我发现的最佳解决方案。

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 管理器 反转后的Sameer:reemaS 反转后的单个字符 a:a 反向后的空值:空 反转后的拉胡尔:luhaR

【讨论】:

【参考方案10】:
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"

【讨论】:

【参考方案11】:

在 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;

    

【讨论】:

【参考方案12】:
import java.util.Scanner;

public class recursion
    public static void main (String []args)

    Scanner scan = new Scanner(System.in);
    System.out.print("Input: ");
    String input = scan.nextLine();

    System.out.print("Reversed: ");
    System.out.println(reverseStringVariable(input));

    public static String reverseStringVariable(String s) 
        String reverseStringVariable = "";

        for (int i = s.length() - 1; i != -1; i--) 
            reverseStringVariable += s.charAt(i);

        

        return reverseStringVariable;
    

【讨论】:

【参考方案13】:
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));
 

这是一个示例代码 sn-p,这可能会对您有所帮助。为我工作。

【讨论】:

【参考方案14】:
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));
   

【讨论】:

【参考方案15】:

内联样本;

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

【讨论】:

【参考方案16】:

AFAIK,每个递归函数都有两件事:

    总有一个停止条件是:

    如果 ((null == str) || (str.length()

    递归使用 stack 内存,该内存使用 LIFO 机制,这就是发生还原的原因。

【讨论】:

【参考方案17】:

试试这个:

public static String reverse(String str) 
   return (str == null || str.length()==0) ? str : reverseString2(str.substring(1))+str.charAt(0);

【讨论】:

以上是关于在 Java 中使用递归反转字符串的主要内容,如果未能解决你的问题,请参考以下文章

由字符串反转(使用递归)引申出来一道Java面试题

Java中如何实现字符串反转?

我想反转堆栈,但我不知道如何使用递归来反转这个......如何在不使用递归的情况下反转堆栈

如何用JS实现字符串反转

C++:使用递归反转字符串

递归字符串反转函数