Java中反转字符串

589

9
@JRL 应该把代码改为 String ih = "dlroW olleH"; System.out.println(ih);,这样可以输出“Hello World”。 - Matthew Farwell
4
我希望我能撤回我投的关闭票(作为重复问题)。我重新阅读了其他问题,意识到它与这个问题有微妙的不同。但是,在整个网站上,这个问题仍然被重复提问很多次。可能应该找一个不同的问题来标记这个问题是重复的。 - Rob Hruska
38个回答

1198
你可以使用这个:
new StringBuilder(hi).reverse().toString()

Java 5新增了StringBuilder类,而在Java 5之前的版本中可以使用StringBuffer类代替,因为它们具有相同的API。


14
感谢评论区指出 StringBuilder 是现今首选。明确提到 StringBuffer 在考虑线程安全时是更好的选择,否则可以使用 StringBuilder。但 StringBuilder 并不取代 StringBuffer。 - ha9u63a7
18
在这种使用本地临时 StringBuilder 的情况下,并不需要考虑并发性(我认为这就是他的意思)。 - xehpuk
2
以下是了解两者之间精确差异的链接:http://www.javatpoint.com/difference-between-stringbuffer-and-stringbuilder 简而言之:StringBuilder比StringBuffer更高效。它不是线程安全的,即多个线程可以同时调用StringBuilder的方法。 - Vishnu Narang
1
这对于 BMP 之外的 Unicode 字符以及组合字符是不起作用的。 - nau
2
@Daniel Brockman,感谢您的简洁明了的回答。在这里,OP说:“我将“Hello World”存储在一个名为hi的字符串变量中。” 这意味着 String hi = "Hello World";。因此,我认为在您的答案中不应该有任何双引号围绕 hi。我的意思是它应该像这样:new StringBuilder(hi).reverse().toString() - Md. Abu Nafee Ibna Zahid

122

对于不允许使用StringBuilderStringBuffer在线评测题目,您可以使用char[]进行原地操作,方法如下:

public static String reverse(String input){
    char[] in = input.toCharArray();
    int begin=0;
    int end=in.length-1;
    char temp;
    while(end>begin){
        temp = in[begin];
        in[begin]=in[end];
        in[end] = temp;
        end--;
        begin++;
    }
    return new String(in);
}

只是提醒一下,对于占用两个字节的“字符”,这将会失败得很惨。 - Minas Mina
3
通常情况下,对于占用2个字节的大多数字符,它都可以正常工作。但是,它无法正常处理在UTF-16中占用2个16位码元的Unicode代码点。 - Stephen C

71

4
好的解决方案(1+)。一个改进建议- StringBuilder(自Java5起)比StringBuffer更快。敬礼。 - Michał Šrajer
35
在一般情况下,这种方法行不通,因为它没有考虑到Unicode中某些“字符”由代理对表示,即两个Java字符,这种解决方案将导致代理对顺序错误。根据JavaDoc,StringBuilder的reverse方法应该是可行的:http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html#reverse()。 - Ian Fairman
1
它是否以正确的顺序反转Unicode变音符号? - rogerdpack

68
String string="whatever";
String reverse = new StringBuffer(string).reverse().toString();
System.out.println(reverse);

8
它的时间复杂度是多少?是O(N)还是更高?其中N等于字符串的长度。 - Mukit09
O(n) 因为它至少需要遍历一次字符串中的字符。 - PlsWork

29

我将使用以下两种方法进行操作:

按字符反转字符串:

public static void main(String[] args) {
    // Using traditional approach
    String result="";
    for(int i=string.length()-1; i>=0; i--) {
        result = result + string.charAt(i);
    }
    System.out.println(result);

    // Using StringBuffer class
    StringBuffer buffer = new StringBuffer(string);
    System.out.println(buffer.reverse());    
}

按单词反转字符串:

public static void reverseStringByWords(String string) {
    StringBuilder stringBuilder = new StringBuilder();
    String[] words = string.split(" ");

    for (int j = words.length-1; j >= 0; j--) {
        stringBuilder.append(words[j]).append(' ');
    }
    System.out.println("Reverse words: " + stringBuilder);
}

最好使用 StringBuilder/StringBuffer 来声明 result 变量,以避免多次创建对象! - Ehsan Mashhadi

20

请查看 Java 6 API 中的 StringBuffer 部分

String s = "sample";
String result = new StringBuffer(s).reverse().toString();

这比StringBuilder更好吗? - CamHart
@CamHart 不,它更慢,但可能只是微小的一点点。 - jcsahnwaldt Reinstate Monica
1
一项几乎有1亿次方法调用的小基准测试显示StringBuffer和StringBuilder之间存在显着差异:https://dev59.com/dnRC5IYBdhLWcg3wROzk#2771852 但在这种情况下,只有两个调用(reverse()toString()),因此差异可能甚至无法测量。 - jcsahnwaldt Reinstate Monica

16

这里是一个使用递归的例子:

public void reverseString() {
    String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    String reverseAlphabet = reverse(alphabet, alphabet.length()-1);
}

String reverse(String stringToReverse, int index){
    if(index == 0){
        return stringToReverse.charAt(0) + "";
    }

    char letter = stringToReverse.charAt(index);
    return letter + reverse(stringToReverse, index-1);
}

2
已经有更好的答案了,特别是@DanielBrockman的。如果标准库中已经存在算法,就没有必要手工制作它并重新发明轮子。 - Willi Mentzel
18
“更好的答案”这个概念是主观的,对某些人来说可能正是他们所寻找的。 - C0D3LIC1OU5
2
OP已经说明“Java中已经内置了某种函数来执行此操作”,因此他的目标是确切地知道这个“函数”是什么。发布与实际问题无关的答案是毫无意义的。如果有人要求自定义实现,您的回答就是合理的,在这种情况下则不是。 - Willi Mentzel
以下是Jon Skeet对于那个小加号和字符串的问题做出的很好的解释:http://jonskeet.uk/csharp/stringbuilder.html (他在写C#,但在Java中基本上是一样的。) - jcsahnwaldt Reinstate Monica
1
也许你没有阅读http://jonskeet.uk/csharp/stringbuilder.html,或者你没有理解它。提示:如果您一次性创建一个字符串,则字符串连接是可以的,但是如果您在循环中构建一个字符串(在这种情况下,递归是一种循环),则不行。是的,当人们在SO上发布糟糕的代码并且甚至不理解其中的问题时,我会有点个人化。再见。 - jcsahnwaldt Reinstate Monica
显示剩余2条评论

12

我只是出于娱乐目的,尝试使用栈。这是我的代码:

public String reverseString(String s) {
    Stack<Character> stack = new Stack<>();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        stack.push(s.charAt(i));
    }
    while (!stack.empty()) {
        sb.append(stack.pop());
    }
    return sb.toString();

}

12

这里是一个低级别的解决方案:

import java.util.Scanner;

public class class1 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String inpStr = in.nextLine();
        System.out.println("Original String :" + inpStr);
        char temp;
        char[] arr = inpStr.toCharArray();
        int len = arr.length;
        for(int i=0; i<(inpStr.length())/2; i++,len--){
            temp = arr[i];
            arr[i] = arr[len-1];
            arr[len-1] = temp;
        }

        System.out.println("Reverse String :" + String.valueOf(arr));
    }
}

12
使用 charAt() 方法
String name = "gaurav";
String reversedString = "";
    
for(int i = name.length() - 1; i >= 0; i--){
    reversedString += name.charAt(i);
}

System.out.println(reversedString);

使用toCharArray()方法
String name = "gaurav";
char [] stringCharArray = name.toCharArray();
String reversedString = "";
    
for(int i = stringCharArray.length - 1; i >= 0; i--) {
    reversedString += stringCharArray[i];
}

System.out.println(reversedString);

使用StringBuilderreverse()方法
String name = "gaurav";
    
String reversedString = new StringBuilder(name).reverse().toString();
    
System.out.println(reversedString);

检查一下https://coderolls.com/reverse-a-string-in-java/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接