Java中逐字反转字符串

6

我有以下代码可以逐词反转字符串,但是我有一个问题,首先,有人能指出如何改进代码吗?其次,我该怎么去掉新字符串开头的空格。

String str = "hello brave new world";
tStr.reverseWordByWord(str)

public String reverseWordByWord(String str){
        int strLeng = str.length()-1;
        String reverse = "", temp = "";

        for(int i = 0; i <= strLeng; i++){
            temp += str.charAt(i);
            if((str.charAt(i) == ' ') || (i == strLeng)){
                for(int j = temp.length()-1; j >= 0; j--){
                    reverse += temp.charAt(j);
                    if((j == 0) && (i != strLeng))
                        reverse += " ";
                }
                temp = "";
            }
        }

        return reverse;
    }

目前这个词组变成了:

olleh evarb wen dlrow

请注意新字符串开头的空格。


你的代码只需编辑for循环即可正常工作,例如:if((str.charAt(i) == ' ') || (i == strLeng)){ if(i==strLeng){ temp+=" "; } for(int j = temp.length()-2; j >= 0; j--){ 但如果你正在寻找更好的编码方式,Dawood已经提供了最简单和内置的方法。 - prajeesh kumar
什么是“更好的代码”?更快?更简洁?更“优雅”或“巧妙”?更易于阅读和维护?这显然需要基于个人观点的答案。 - Stephen C
37个回答

7
如果str =“The quick brown fox jumped over the lazy dog!” 它会像这样返回:“dog!lazy the over jumped fox brown quick The”...
  private static String Reverse(String str) {
      char charArray[] = str.toCharArray();
    for (int i = 0; i <str.length(); i++){
        if(charArray[i] == ' ')
        return Reverse(str.substring(i + 1)) + str.substring(0, i) + " ";
    }

    return str + " ";
}

如果你正在使用charArray,那为什么不选择字符串数组呢?这样会更容易。 - happs

7
不使用split函数,代码将如下所示:

public static void reverseSentance(String str) {
    StringBuilder revStr = new StringBuilder("");
    int end = str.length(); // substring takes the end index -1
    int counter = str.length()-1;
    for (int i = str.length()-1; i >= 0; i--) {     
        if (str.charAt(i) == ' ' || i == 0) {
            if (i != 0) {
                revStr.append(str.substring(i+1, end));
                revStr.append(" ");
            }
            else {
                revStr.append(str.substring(i,end));
            }
            end = counter;
        }
        counter--;
    }
    System.out.println(revStr);
}

你可以移除 counter 变量并将其替换为 i,同时移除 counter-- 行。 - Doronz

3
这里是如何操作的方法:
    StringBuilder result = new StringBuilder();
    StringTokenizer st = new StringTokenizer(input, " ");
    while (st.hasMoreTokens()) {
        StringBuilder thisToken = new StringBuilder(st.nextToken());
        result.append(thisToken.reverse() + " ");
    }
    String resultString = result.toString();

这不太对。它假设句子中的所有单词都必须由空格分隔。当遇到标点符号时会发生什么? - eternaln00b
好观点。我只是根据OP的代码发布了一个快速解决方案,因为他也在空格上进行了分隔(第10行:if (str.charAt(i) == ' '))。你说得对,为了得到全面的解决方案,还需要添加其他分隔符。 - Dawood

2

我的方法使用StringUtils。在单元测试中。

@Test
public void testReversesWordsAndThenAllCharacters(){
    String sentence = "hello brave new world";
    String reversedWords = StringUtils.reverseDelimited(sentence, ' ');
    String reversedCharacters = StringUtils.reverse(reversedWords);
    assertEquals("olleh evarb wen dlrow", reversedCharacters);
}

如果您静态导入了StringUtils,那么这可以被内联为:
reverse(reverseDelimited("hello brave new world", ' '))

1

我会首先将反转单词的代码与逐个反转单词的代码分开。这个内部循环:

for(int j = temp.length()-1; j >= 0; j--)
{
    reverse += temp.charAt(j);
    if((j == 0) && (i != strLeng))
        reverse += " ";
}

这将是一个函数/方法调用。

另外,为了使您的代码更具性能,而不是使用+运算符连接字符串,我建议使用字符串缓冲区类。例如StringBufferStringBuilder


顺便提一下,StringBuilder 自带一个 reverse() 方法。 - Louis Wasserman

1

你觉得使用这样的代码怎么样?

String string="yourWord";
String reverse = new StringBuffer(string).reverse().toString();

我本来会用这个的,但是我正在为面试练习,他们不允许我使用这个或者分词器。 - Tsundoku
@LuisArmando 好的,那么这是对“第一个问题:有人能指出如何改进代码吗?”的回答。 - shadyabhi
没错,谢谢你指出来,因为我本来也不会这样做(缺乏实践)。 - Tsundoku

1

试试这个。它考虑了任何类型的标点符号和空格字符。

public String reverseWordByWord(String inputStr)
{
    BreakIterator wordIterator = BreakIterator.getWordInstance();
    wordIterator.setText(inputStr);
    int start = wordIterator.first();
    StringBuilder tempBuilder;
    StringBuilder outBuilder = new StringBuilder();
    for (int end = wordIterator.next(); end != BreakIterator.DONE; start = end, end = wordIterator.next())
    {
        tempBuilder = new StringBuilder(inputStr.substring(start, end));
        outBuilder.append(tempBuilder.reverse());
    }
    return outBuilder.toString();
}

它甚至与语言环境无关。 :) 句子“hello brave new world. I am here to stay.”变成了“olleh evarb wen dlrow. I ma ereh ot yats.” - eternaln00b

1
这里有一种编程技巧,使用流行的 split() 函数(在所有主要语言中都可用),Java 的 toCharArray() 函数(适用于完全控制字符串中的字符),以及 Java 的 StringBuilder 类(也适用于 C#)以提高性能。

我认为与其他发布的答案相比,该代码更易于理解。

public static String reverseWordByWord(String sentence) {
    StringBuilder result = new StringBuilder();
    String[] words = sentence.split("\\s+");   // space(s) are the delimiters

    for (String word : words) {
        char[] charArray = word.toCharArray();
        int iEnd = word.length() - 1;

        StringBuilder temp = new StringBuilder();
        for (int i = iEnd; i >= 0; i--) {
            temp.append(charArray[ i]);
        }
        result.append(temp);
        result.append(" ");     // separate the words
    }
    return result.toString().trim();    // remove the trailing spaces
}

作者发布的要求提醒。
示例输入: "Hello World"
输出: "olleH dlroW"


1
public static void reverseByWord(String s) {

        StringTokenizer token = new StringTokenizer(s);

        System.out.println(token.countTokens());
        Stack<String> stack = new Stack<String>();
        while (token.hasMoreElements()) {
            stack.push(token.nextElement().toString());
        }

        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }

1
另一种不使用split方法的解决方案。
    public static String reverseWordsWithoutSplit(String str) {
    StringBuffer buffer = new StringBuffer();
    int length = str.length();
    while(length >0) {
        int wordstart = length -1;
        while(wordstart >0 && str.charAt(wordstart) != ' '){
            wordstart--;
        }
        buffer.append(str.substring(wordstart==0?wordstart:wordstart+1, length));
        if(wordstart>0)
            buffer.append(" ");
        length = wordstart;
    }
    return buffer.toString();
}

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