Whats the best way to recursively reverse a string in Java?

后端 未结 26 2520
一个人的身影
一个人的身影 2020-11-27 14:56

I have been messing around with recursion today. Often a programming technique that is not used enough.

I set out to recursively reverse a string. Here\'s what I cam

相关标签:
26条回答
  • 2020-11-27 15:40

    In Java, since the String is immutable, the String concatenation would be more complex than it looks like.

    For every concatenation, it creates a new string copying the contents of original String resulting in a linear complexity O(n) where n is the length of the string, so for m such operations it is O(m*n), we can say it is of quadratic complexity O(n^2).

    We can use a StringBuilder which has O(1) complexity for each append. Below is the recursive program using StringBuilder. This uses only n/2 stack frames, so it has less space complexity than the normal recursive call which would be like s.charAt(s.length-1) + reverse(s.subString(0, s.length-2);

    public class StringReverseRecursive {
        public static void main(String[] args) {
            String s = "lasrever gnirts fo noitatnemelpmi evisrucer a si sihT";
            StringBuilder sb = new StringBuilder(s);
            reverse(s, sb, 0, sb.length() - 1);
            System.out.println(sb.toString());
        }
    
        public static void reverse(String s, StringBuilder sb, int low, int high) {
            if (low > high)
                return;
            sb.setCharAt(low, s.charAt(high));
            sb.setCharAt(high, s.charAt(low));
            reverse(s, sb, ++low, --high);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 15:42

    You don't want to nest too deeply. Divide-and-conquer is the way to go. Also reduces total size of temporary strings and is amenable to parallelisation.

    public static String reverseString(String str) {
        int len = str.length();
        return len<=1 ? str : (
            reverseString(str.substring(len/2))+
            reverseString(str.substring(0, len/2))
        );
    }
    

    (Not tested - this is stackoverflow.)

    String.concat instead of + would improve performance at the expense of clarity.

    Edit: Just for fun, a tail-recursion friendly version of the naive algorithm.

    public static String reverseString(String str) {
        return reverseString("", str);
    }
    private static String reverseString(String reversed, String forward) {
        return forward.equals("") ? reversed : (
             reverseString(reversed+forward.charAt(0), forward.substring(1)) 
        );
    }
    

    Correct handling of surrogate pairs is left to the interested reader.

    0 讨论(0)
  • 2020-11-27 15:45

    You capture the basic idea, but extracting the last character doesn't improve clarity. I'd prefer the following, others might not:

    public class Foo
    {
        public static void main(String[] argv) throws Exception
        {
            System.out.println(reverse("a"));
            System.out.println(reverse("ab"));
            System.out.println(reverse("abc"));
        }
    
    
        public final static String reverse(String s)
        {
            // oft-repeated call, so reduce clutter with var
            int length = s.length();
    
            if (length <= 1)
                return s;
            else
                return s.substring(length - 1) + reverse(s.substring(0, length - 1));
        }
    }
    
    0 讨论(0)
  • 2020-11-27 15:47

    This is what I've found to work and use recursive. You can pass str.length() as strLength argument

    private static String reverse(String str, int strLength) {
        String result = "";
        if(strLength > 0)
            result = str.charAt(strLength - 1) + reverse(str, strLength - 1);
        return result;
    }
    
    0 讨论(0)
  • 2020-11-27 15:47

    If you think less code is good then....

    static String reverse(String str){
        return str.length()>=2 ? str.charAt(str.length()-1) + reverse(str.substring(0,str.length()-1)) : str ;
    }
    
    0 讨论(0)
  • 2020-11-27 15:47
    public static String reverse(String s){
    
        int n = s.length()-1;
    
        if(n >=0)
        return  s.substring(s.length()-1)+ReverseString(s.substring(0,n--));
        else return "";
    }
    
    0 讨论(0)
提交回复
热议问题