Инвертировать каждое отдельное слово строки «Hello World» с помощью Java - PullRequest
38 голосов
/ 14 марта 2010

Я хочу изменить каждое отдельное слово строки в Java (не всю строку, только каждое отдельное слово).

Пример: если входной строкой является «Hello World», то выходной должен быть «olleH dlroW».

Ответы [ 30 ]

106 голосов
/ 14 марта 2010

Это должно сработать. Это будет выполнять итерацию по каждому слову в исходной строке, инвертировать его с помощью встроенного метода reverse() StringBuilder и выводить обратное слово.

String source = "Hello World";

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

Выход:

olleH dlroW 

Примечания: Комментаторы правильно указали на несколько вещей, которые, я думал, мне следует упомянуть здесь. Этот пример добавит дополнительный пробел в конец результата. Он также предполагает, что ваши слова разделены одним пробелом, а предложение не содержит знаков препинания.

47 голосов
/ 14 марта 2010

Знай свои библиотеки; -)

import org.apache.commons.lang.StringUtils;

String reverseWords(String sentence) {
    return StringUtils.reverseDelimited(StringUtils.reverse(sentence), ' ');
}
23 голосов
/ 14 марта 2010

Вы должны сделать это для каждого слова после split в array слов.

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);
}
17 голосов
/ 14 марта 2010

Вот простейшее решение, в котором даже не используются циклы.

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

Даже если это домашнее задание, не стесняйтесь копировать его и отправлять как свое собственное. Вы либо получите дополнительный кредит (если сможете объяснить, как это работает), либо попадете на плагиат (если не сможете).

8 голосов
/ 29 ноября 2013

Никто здесь не рассматривает символы Юникода. Вам нужно использовать java.text.BreakIterator, чтобы найти границы слов, а затем использовать еще один в пределах каждой границы слов, чтобы перечислить границы символов:

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"

Использование описанных выше наивных методов сместит диакритический знак \u0308 над первым l при обращении String. Вы хотите, чтобы он оставался выше e.

5 голосов
/ 29 августа 2011

Ну, я парень на C / C ++, практикую Java для интервью, дай мне знать, если что-то можно изменить или улучшить Следующее позволяет использовать несколько пробелов и символов новой строки.

Первый использует 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();
}

Этот использует char []. Я думаю, что это более эффективно ...

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);
}
4 голосов
/ 15 марта 2010

Я предполагаю, что вы можете просто напечатать результаты (вы только что сказали, что «результат должен быть ...»); -)

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

Или возвращать обратную строку:

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();
}
4 голосов
/ 14 декабря 2013

Использование только substring() и рекурсия:

public String rev(String rest) {
    if (rest.equals(""))
        return "";
    return rev(rest.substring(1)) + rest.substring(0,1);
}
3 голосов
/ 14 марта 2010

Учитывая, что разделителем может быть несколько пробелов / табуляций и что мы хотим сохранить их:

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

}
1 голос
/ 07 января 2013

Я придумал этот ответ, работая над проблемой. Я пытался не использовать вложенный для решения цикла O (N ^ 2). Я как бы заставил себя использовать стек для удовольствия: 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;
    }
...