开发者

Reverse each individual word of "Hello World" string with Java

开发者 https://www.devze.com 2022-12-23 08:05 出处:网络
I want to reverse each individual word of a String in Java (not the entire string, just each individual word).

I want to reverse each individual word of a String in Java (not the entire string, just each individual word).

Example: if input String is "Hello Wor开发者_运维知识库ld" then the output should be "olleH dlroW".


This should do the trick. This will iterate through each word in the source string, reverse it using StringBuilder's built-in reverse() method, and output the reversed word.

String source = "Hello World";

for (String part : source.split(" ")) {
    System.out.print(new StringBuilder(part).reverse().toString());
    System.out.print(" ");
}

Output:

olleH dlroW 

Notes: Commenters have correctly pointed out a few things that I thought I should mention here. This example will append an extra space to the end of the result. It also assumes your words are separated by a single space each and your sentence contains no punctuation.


Know your libraries ;-)

import org.apache.commons.lang.StringUtils;

String reverseWords(String sentence) {
    return StringUtils.reverseDelimited(StringUtils.reverse(sentence), ' ');
}


You need to do this on each word after you split into an array of words.

public String reverse(String word) {
    char[] chs = word.toCharArray();

    int i=0, j=chs.length-1;
    while (i < j) {
        // swap chs[i] and chs[j]
        char t = chs[i];
        chs[i] = chs[j];
        chs[j] = t;
       i++; j--;
    }
    return String.valueOf(chs);
}


Here's the simplest solution that doesn't even use any loops.

public class olleHdlroW {
    static String reverse(String in, String out) {
        return (in.isEmpty()) ? out :
            (in.charAt(0) == ' ')
            ? out + ' ' + reverse(in.substring(1), "")
            : reverse(in.substring(1), in.charAt(0) + out);
    }
    public static void main(String args[]) {
        System.out.println(reverse("Hello World", ""));
    }
}

Even if this is homework, feel free to copy it and submit it as your own. You'll either get an extra credit (if you can explain how it works) or get caught for plagiarism (if you can't).


No one here is considering unicode characters. You need to use java.text.BreakIterator to find word boundaries and then use another one within each word boundary to enumerate character boundaries:

String helloWorld = "He\u0308llo World"; // Hëllo World
StringBuilder reverseStringBuilder = new StringBuilder(helloWorld.length());
BreakIterator wordBreakIterator = BreakIterator.getWordInstance();
wordBreakIterator.setText(helloWorld);

int wordStart = wordIterator.first();
int wordEnd = wordIterator.next();

while (wordEnd != BreakIterator.DONE) {
    String word = helloWorld.substring(wordStart,wordEnd);
    if (Character.isLetterOrDigit(word.charAt(0))) {
        // "Hello" or "World" in our example
        BreakIterator characterBreakIterator = BreakIterator.getCharacterInstance();
        characterBreakIterator.setText(word);
        int characterEnd = characterBreakIterator.last();
        int characterStart = characterBreakIterator.previous();
        while (characterStart != BreakIterator.DONE) {
            reverseStringBuilder.append(word.substring(characterStart, characterEnd));

            characterEnd = characterStart;
            characterStart = characterBreakIterator.previous();
        }
    } else {
        // " " in our example
        reverseStringBuilder.append(word);
    }
    wordStart = wordEnd;
    wordEnd = wordIterator.next();
}

String dlroWolleh = reverseStringBuilder.toString(); // "dlroW ollëH"

Using naive methods above will shift the diacritic character \u0308 above the first l when you reverse the String. You want it to stay above the e.


Well I'm a C/C++ guy, practicing java for interviews let me know if something can be changed or bettered. The following allows for multiple spaces and newlines.

First one is using StringBuilder

public static String reverse(String str_words){
    StringBuilder sb_result = new StringBuilder(str_words.length());
    StringBuilder sb_tmp = new StringBuilder();
    char c_tmp;
    for(int i = 0; i < str_words.length(); i++){
        c_tmp = str_words.charAt(i);    
        if(c_tmp == ' ' || c_tmp == '\n'){
            if(sb_tmp.length() != 0){   
                sb_tmp.reverse();
                sb_result.append(sb_tmp);
                sb_tmp.setLength(0);
            }   
            sb_result.append(c_tmp);
        }else{
            sb_tmp.append(c_tmp);
        }
    } 
    if(sb_tmp.length() != 0){
        sb_tmp.reverse();
        sb_result.append(sb_tmp);
    }
    return sb_result.toString();
}

This one is using char[]. I think its more efficient...

public static String reverse(String str_words){
    char[] c_array = str_words.toCharArray();
    int pos_start = 0;
    int pos_end;
    char c, c_tmp; 
    int i, j, rev_length;
    for(i = 0; i < c_array.length; i++){
        c = c_array[i];
        if( c == ' ' || c == '\n'){
            if(pos_start != i){ 
                pos_end = i-1;
                rev_length = (i-pos_start)/2;
                for(j = 0; j < rev_length; j++){
                    c_tmp = c_array[pos_start+j];
                    c_array[pos_start+j] = c_array[pos_end-j];
                    c_array[pos_end-j] = c_tmp;
                }
            }
            pos_start = i+1;
        }
    }
    //redundant, if only java had '\0' @ end of string
    if(pos_start != i){
        pos_end = i-1;
        rev_length = (i-pos_start)/2;
        for(j = 0; j < rev_length; j++){
            c_tmp = c_array[pos_start+j];
            c_array[pos_start+j] = c_array[pos_end-j];
            c_array[pos_end-j] = c_tmp;
        }
    }   
    return new String(c_array);
}


I'm assuming you could just print the results (you just said 'the output should be...') ;-)

String str = "Hello World";
for (String word : str.split(" "))
    reverse(word);

void reverse(String s) {
    for (int idx = s.length() - 1; idx >= 0; idx--) 
        System.out.println(s.charAt(idx));
}

Or returning the reversed String:

String str = "Hello World";
StringBuilder reversed = new StringBuilder();
for (String word : str.split(" ")) {
  reversed.append(reverse(word));
  reversed.append(' ');
}
System.out.println(reversed);

String reverse(String s) {
  StringBuilder b = new StringBuilder();
  for (int idx = s.length() - 1; idx >= 0; idx--)
      b.append(s.charAt(idx));
  return b.toString();
}


Using only substring() and recursion:

public String rev(String rest) {
    if (rest.equals(""))
        return "";
    return rev(rest.substring(1)) + rest.substring(0,1);
}


Taking into account that the separator can be more than one space/tab and that we want to preserve them:

public static String reverse(String string)
{
    StringBuilder sb = new StringBuilder(string.length());
    StringBuilder wsb = new StringBuilder(string.length());
    for (int i = 0; i < string.length(); i++)
    {
        char c = string.charAt(i);
        if (c == '\t' || c == ' ')
        {
            if (wsb.length() > 0)
            {
                sb.append(wsb.reverse().toString());
                wsb = new StringBuilder(string.length() - sb.length());
            }
            sb.append(c);
        }
        else
        {
            wsb.append(c);
        }
    }
    if (wsb.length() > 0)
    {
        sb.append(wsb.reverse().toString());
    }
    return sb.toString();

}


Heres a method that takes a string and reverses it.

public String reverse ( String s ) {
            int length = s.length(), last = length - 1;
            char[] chars = s.toCharArray();
            for ( int i = 0; i < length/2; i++ ) {
                char c = chars[i];
                chars[i] = chars[last - i];
                chars[last - i] = c;
            }
            return new String(chars);
        }

First you need to split the string into words like this

String sample = "hello world";  
String[] words = sample.split(" ");  


I came up with this answer while working on the problem. I tried not to use nested for loop solution O(N^2). I kind of forced myself to use stack for fun :D

    public StringBuilder reverseWord(String input) {
        char separator = ' ';
        char[] chars = input.toCharArray();
        Stack<Character> stack = new Stack<Character>();
        StringBuilder sb = new StringBuilder(chars.length);


        for(int i = 0; i < chars.length; i++) {

            if(chars[i] != separator) { //letters
                stack.push(chars[i]);

                //if not last letter don't go any further
                if(i != chars.length - 1) { continue; }

            }

            while(!stack.isEmpty()) {
                sb.append(stack.pop());
            }
            sb.append(separator);

        }
        //remove the last separator
        sb.deleteCharAt(sb.length() - 1);
        return sb;
    }


public static void main(String[] args) {
        System.out.println(eatWord(new StringBuilder("Hello World This Is Tony's Code"), new StringBuilder(), new StringBuilder()));
    }
static StringBuilder eatWord(StringBuilder feed, StringBuilder swallowed, StringBuilder digested) {
    for (int i = 0, size = feed.length(); i <= size; i++) {
        if (feed.indexOf(" ") == 0 || feed.length() == 0) {
            digested.append(swallowed + " ");
            swallowed = new StringBuilder();
        } else {
            swallowed.insert(0, feed.charAt(0));
        }
        feed = (feed.length() > 0)  ? feed.delete(0, 1) : feed ;
    }
    return digested;
}

run:

olleH dlroW sihT sI s'ynoT edoC 
BUILD SUCCESSFUL (total time: 0 seconds)


Using split(), you just have to change what you wish to split on.

public static String reverseString(String str)
{
    String[] rstr;
    String result = "";
    int count = 0;
    rstr = str.split(" ");
    String words[] = new String[rstr.length];
    for(int i = rstr.length-1; i >= 0; i--)
    {
        words[count] = rstr[i];
        count++;
    }

    for(int j = 0; j <= words.length-1; j++)
    {
        result += words[j] + " ";
    }

    return result;


}


    String input = "Hello World!";

    String temp = "";
    String result = "";

    for (int i = 0; i <= input.length(); i++) {
        if (i != input.length() && input.charAt(i) != ' ') {
            temp = input.charAt(i) + temp;
        } else {
            result = temp + " " + result;
            temp = "";
        }
    }

    System.out.println("the result is: " + result);


class ReverseWordsInString{
    public static String reverse(String s1){
            int l = s1.length();
            if (l>1)
                    return(s1.substring(l-1) + reverse(s1.substring(0,l-1)));
            else
                    return(s1.substring(0));
    }
    public static void main(String[] args){
            String st = "Hello My World!";
            String r = "";
            for (String word : st.split(" "))
                    r += " "+ reverse(word);
            System.out.println("Reversed words in the given string: "+r.trim());
    }
}


Use split() function and reverse individual words

    public String reverseSentence(String input)
      {
        String[] words = input.split(" ");
        StringBuilder builder = new StringBuilder();
        for (String s : words)
        {
            String rev = " ";
            for (int i = 0; i < s.length(); i++)
            {
                rev = s.charAt(i) + rev;
            }

            builder.append(rev);
        }

        return builder.toString().trim();
      }

Remove the extra space that is added at the end of the new String using trim()

Output:

    This is my sentence        
    sihT si ym ecnetnes        


public String reverse(String arg) {
    char[] s = arg.toCharArray();
    StringBuilder sb = new StringBuilder();
    boolean reverse = false;
    boolean isChar = false;
    int insertPos = 0;

    for (int i = 0; i < s.length; i++) {
        isChar = Character.isAlphabetic(s[i]);
        if (!reverse && isChar) {
            sb.append(s[i]);
            insertPos = i;
            reverse = true;
        } else if (reverse && isChar) {
            sb.insert(insertPos, s[i]);
        } else if (!reverse && !isChar) {
            sb.append(s[i]);
        } else if (reverse && !isChar) {
            reverse = false;
            sb.append(s[i]);
        }
    }

    return sb.toString();
}


 package MujeebWorkspace.helps;
 // javamujeeb@gmail.com

 public class Mujeeb {

     static String str= "This code is simple to reverse the word without changing positions";
     static String[] reverse = str.split(" ");

     public static void main(String [] args){  
         reverseMethod();
     }

     public static void reverseMethod(){
         for (int k=0; k<=reverse.length-1; k++) {
             String word =reverse[reverse.length-(reverse.length-k)];
             String subword = (word+" ");
             String [] splitsubword = subword.split("");

             for (int i=subword.length(); i>0; i--){
                 System.out.print(splitsubword[i]);  
             }
         }
     }
 }


with and without api.

public class Reversal {
    public static void main(String s[]){
        String str= "hello world";
        reversal(str);
    }

    static void reversal(String str){
        String s[]=str.split(" ");
        StringBuilder noapi=new StringBuilder();
        StringBuilder api=new StringBuilder();
        for(String r:s){
            noapi.append(reversenoapi(r));
            api.append(reverseapi(r));
        }
        System.out.println(noapi.toString());
        System.out.println(api.toString());
    }

    static String reverseapi(String str){
        StringBuilder sb=new StringBuilder();
        sb.append(new StringBuilder(str).reverse().toString());
        sb.append(' ');
        return sb.toString();

    }

    static String reversenoapi(String str){
        StringBuilder sb=new StringBuilder();
        for(int i=str.length()-1;i>=0;i--){
            sb.append(str.charAt(i));
        }
        sb.append(" ");
        return sb.toString();
    }
}


Reverse copy the string block-wise and then concatenate the whitespaces. for eg. "hello java world".

1st block = "hello" reverse copy it:- "olleh" and add whitespace then
2nd block = "java" etc.

public static void main(String args[]) {
    String s, rev = "";
    Scanner in = new Scanner(System.in);

    System.out.println("Enter a string to reverse");
    s = in.nextLine();

    int length = s.length();
    // char[] cs=s.toCharArray();
    int l, r;
    int i = 0;
    while (i < length) {
        l = i; // starting index
        // find length of sub-block to reverse copy
        while (i < length && s.charAt(i) != ' ') { 
            i++;
        }
        r = i - 1; // ending index
        for (int j = r; j >= l; j--) { // copy reverse of sub-block
            rev = rev + s.charAt(j);
        }
        rev = rev + " "; // add the whitespace
        i++;
    }

    System.out.println("Reverse of entered string is: " + rev);
}

Program also works for multiple whitespaces between words.


Some of the above solutions are of the higher run time complexities. With the below algorithm, it can be achieved in O(n) time.

Algorithm:

  1. Parse the String from the end to beginning.
  2. Every time a space character is encountered i.e. " ", put the list of characters parsed till then in an ArrayList which can grow dynamically.
  3. Print the ArrayList in the reverse order which gives you the desired output.

Complexity: O(n) where n is the length of the String.

import java.io.IOException;
import java.util.ArrayList;

public class WordReverse {

    public static void main(String[] args) throws IOException {

        String inputStr = "Hello World";
        String reversed = "";
        ArrayList<String> alist = new ArrayList<String>();

        for (int i = inputStr.length() - 1; i >= 0; i--) {
            if (inputStr.charAt(i) != ' ') {
                reversed = reversed + inputStr.charAt(i);
            } else {
                alist.add(reversed);
                reversed = "";
            }
        }
        alist.add(reversed);
        String result = "";

        for (int i = alist.size() - 1; i >= 0; i--) {
            result = result + alist.get(i);
            result = result + " ";
        }
        System.out.println(result);
    }
}


Solution with TC - O(n) and SC - O(1)

public String reverseString(String str){
    String str = "Hello Wrold";
    int start = 0;

    for (int i = 0; i < str.length(); i++) {

        if (str.charAt(i) == ' ' || i == str.length() - 1) {

            int end = 0;

            if (i == str.length() - 1) {
                end = i;
            } else {
                end = i - 1;
            }

            str = swap(str, start, end);
            start = i + 1;
        }
    }
    System.out.println(str);
   }

 private static String swap(String str, int start, int end) {

    StringBuilder sb = new StringBuilder(str);

    while (start < end) {
        sb.setCharAt(start, str.charAt(end));
        sb.setCharAt(end, str.charAt(start));
        start++;
        end--;
    }
    return sb.toString();
}


example with stream API

    public static String reverseAllWords(String str) {
    String[] arr = str.split(" ");
    String res = "";
    for (int x = 0; x < arr.length; x++) {
        res = res + Stream.of(arr[x].split("")).reduce("", (a, b) -> b + a) + " ";
    }
    return res;
}


You can reverse a string using the enhanced for loop and swap the summands inside:

public static String reverse(String str) {
    String revStr = "";
    for (char ch : str.toCharArray()) {
        // concat of chars in reverse order
        revStr = ch + revStr;
    }
    return revStr;
}
public static String[] reverse(String[] arr) {
    String[] revArr = new String[arr.length];
    for (int i = 0; i < arr.length; i++) {
        // same word order
        revArr[i] = reverse(arr[i]);
    }
    return revArr;
}
public static void main(String[] args) {
    String[] arr = reverse("Hello World".split(" "));
    System.out.println(String.join(" ", arr));
}

Output:

olleH dlroW


String someString = new String("Love thy neighbor");
    System.out.println(someString);
    char[] someChar = someString.toCharArray();
    int j = someChar.length - 1;
    char temp;
    for (int i = 0; i <= someChar.length / 2; i++) {
        temp = someChar[i];
        someChar[i] = someChar[j];
        someChar[j] = temp;
        j--;
    }
    someString = new String(someChar);
    System.out.println(someString);

Run:

Love thy neighbor
robhgien yht evoL


This reverses the words in the given string. Words are assumed to be separated by a single space. Reversal is done in place (in the character buffer).

public static String reversePhrases(String s)
{
    char[] buf = s.toCharArray();
    int len = buf.length;
    int start = 0;
    for (int i = 0; i < len; i++) {
        if (buf[i] == ' ' || i == (len-1)) {
            if (i == (len-1)) {
                i = len;
            }
            int end = (start + i)/2;
            for (int j = start; j < end; j++) {
                char c = buf[j];
                int pos = (start + i) - j - 1;
                buf[j] = buf[pos];
                buf[pos] = c;
            }
            start = i + 1;    
        }
    }
    return new String(buf);
}


Easy way:

String reverseString(String string)
{
    String newString = "";
    for(int x = string.length() - 1; x > -1; x ++)
        newString += string.charAt(x);
    return newString;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消