Зворотний рядок у Java


467

Я "Hello World"зберігав змінну String на ім'я hi.

Мені потрібно його надрукувати, але перевернутим.

Як я можу це зробити? Я розумію, що в Java вже є якась функція, яка це робить.

Пов'язане: Зверніть на Java кожне окреме слово рядка "Hello World"


7
@JRL дійсно повинен бути String ih = "dlroW olleH"; System.out.println (ih);
Меттью Фарвелл

4
Я б хотів, щоб я міг відкликати своє голосування (як дублікат). Я перечитав інше питання і зрозумів, що воно тонко інше, ніж це. Однак це питання все ще повторюється багато разів на сайті. Напевно, варто просто знайти інше запитання, щоб відзначити цю дупу.
Роб Грушка

ви можете використовувати функцію reverse () класу StringBuilder, метод toCharArray (), заміну символів та багато іншого. див. цей ресурс для додаткових прикладів, flowerbrackets.com/2-best-ways-to-reverse-a-string-in-java
Шива

StringBuilder.reverse () - це більш читабельне та елегантне рішення.
lokesh

Відповіді:


980

Ви можете скористатися цим:

new StringBuilder(hi).reverse().toString()

Або для версій раніше JDK 1.5 використовувати java.util.StringBufferзамість них StringBuilder- вони мають однаковий API. Дякую коментаторам за те, що вони відзначають, що StringBuilderвважають за краще сьогодні, коли немає проблем щодо одночасності.


13
"Дякую коментаторам, що вказали, що StringBuilder в даний час є кращим"? Існує чітка заява, що StringBuffer, якщо безпека потоків викликає занепокоєння. в іншому випадку можна використовувати StringBuilder. StringBuilder не є заміною StringBuffer.
ha9u63ar

15
@ ha9u63ar Для цього сценарію з локальним викидом StringBuilderодночасність не викликає особливих проблем (і я думаю, що це він мав на увазі).
xehpuk

2
Ось посилання, щоб знати точну різницю між двома: javatpoint.com/… коротше: StringBuilder є більш ефективним, ніж StringBuffer. Це не безпечно для потоків, тобто кілька потоків можуть одночасно викликати методи StringBuilder.
Vishnu Narang

Це не буде працювати для символів Unicode за межами BMP, якщо поєднувати символи.
nau

2
@Daniel Brockman, Дякую за вашу приємну та стислу відповідь. Тут ОП сказав, що у мене "Здрастуй світ" зберігається в змінній String з назвою привіт . Це означає String hi = "Hello World";. Так що я думаю , що в своїй відповіді повинна НЕ бути ніякої лапки hi. Я маю на увазі, що це має бути такnew StringBuilder(hi).reverse().toString()
пані Абу Нафей Ібна Захід

109

Для проблем із Інтернет-суддями, які не дозволяють, StringBuilderабо StringBufferви можете це зробити на місці, використовуючи 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);
}

Хоча лише записка. Це жахливо не вдасться до "персонажів", які займають два байти.
Мінас Міна

Насправді це, як правило, добре працює для більшості символів, які займають 2 байти. Насправді це не вдається - це кодові точки Unicode, що займають 2-х 16-бітні кодові одиниці (в UTF-16).
Стівен C

Це хороше рішення, але чи можемо ми зробити те ж саме, якщо у нас є 10k символів у рядку з мінімальною складністю.
Джатіндер Кумар

62
public static String reverseIt(String source) {
    int i, len = source.length();
    StringBuilder dest = new StringBuilder(len);

    for (i = (len - 1); i >= 0; i--){
        dest.append(source.charAt(i));
    }

    return dest.toString();
}

http://www.java2s.com/Code/Java/Language-Basics/ReverseStringTest.htm


4
Гарне рішення (1+). Одне покращення - StringBuilder (оскільки java5) буде швидше, ніж StringBuffer. З повагою
Michał Šrajer

31
У загальному випадку це не працюватиме, оскільки не враховує, що деякі "символи" в унікоді представлені сурогатною парою, тобто двома символами Java, і це рішення призводить до того, що пара знаходиться в неправильному порядку. Зворотний метод StringBuilder має бути нормальним відповідно до JavaDoc: docs.oracle.com/javase/7/docs/api/java/lang/…
Ian Fairman

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

7
У чому складність цього? O (N) або більше? N дорівнює довжині рядка.
Mukit09

O (n), оскільки вона має пройти через символи рядка хоча б один раз.
PlsWork

26

Я роблю це, використовуючи наступні два способи:

Зворотний рядок за CHARACTERS:

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

Зворотний рядок WORDS:

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

19

Погляньте на API Java 6 під StringBuffer

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

це краще, ніж StringBuilder?
CamHart

@CamHart Ні, це повільніше, але, мабуть, лише крихітна трішечка.
jcsahnwaldt каже, що GoFundMonica

1
Невеликий орієнтир із майже 100 мільйонами викликів методів показав істотну різницю між StringBuffer і StringBuilder: stackoverflow.com/questions/355089/… Але в цьому випадку є лише два виклики ( reverse()і toString()), тому різниці, ймовірно, навіть не буде вимірний
jcsahnwaldt каже, що GoFundMonica

17

Ось приклад використання рекурсії:

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's. Якщо алгоритм вже існує у стандартній бібліотеці, немає необхідності його переробляти та винаходити колесо.
Віллі Менцель

14
Концепція "набагато кращої відповіді" є суб'єктивною. Це може бути саме те, що хтось шукає.
C0D3LIC1OU5

2
В ОП вже було заявлено, що "в Java вже є якась функція, яка це робить", тому його метою було точно знати, яка "функція" це. Лише розміщувати відповідь, яка має мало спільного з фактично заданим питанням, не має сенсу. Якщо хтось хотів би попросити користувацьку реалізацію, то ваша відповідь була б виправданою, в цьому випадку це не так.
Віллі Менцель

Downvote. Більшість інших рішень є O (n) і можуть обробляти рядки майже будь-якої довжини, це O (n ^ 2) і має тенденцію до збоїв із StackOverflowError для струн довше ніж 5000 символів (у JDK 8 VM, конфігурація за замовчуванням) .
jcsahnwaldt каже, що GoFundMonica

1. Інші рішення не використовують рекурсії і можуть добре обробляти довгі струни. Чому б ви використовували рекурсію замість ітерації для такого завдання? Це не має сенсу. (Якщо ви не з функціонального фону програмування, що часто призводить до проблем, коли ви пишете код на імперативному мові / OO.) 2. Об'єднання рядків (що невинне маленьке «+») - це O (n). Ви повинні бути новаком у Java, інакше ви це знатимете.
jcsahnwaldt каже, що GoFundMonica

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

Я спробував, просто заради задоволення, за допомогою стека. Ось мій код:

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

}

11

Оскільки наведений нижче метод (за допомогою XOR ) для повернення рядка не вказаний, я приєдную цей метод, щоб повернути рядок.

Алгоритм заснований на:

1. (A XOR B) XOR B = A

2. (A XOR B) XOR A = B

Фрагмент коду:

public class ReverseUsingXOR {
    public static void main(String[] args) {
        String str = "prateek";
        reverseUsingXOR(str.toCharArray());
    }   

    /*Example:
     * str= prateek;
     * str[low]=p;
     * str[high]=k;
     * str[low]=p^k;
     * str[high]=(p^k)^k =p;
     * str[low]=(p^k)^p=k;
     * 
     * */
    public static void reverseUsingXOR(char[] str) {
        int low = 0;
        int high = str.length - 1;

        while (low < high) {
            str[low] = (char) (str[low] ^ str[high]);
            str[high] = (char) (str[low] ^ str[high]);   
            str[low] = (char) (str[low] ^ str[high]);
            low++;
            high--;
        }

        //display reversed string
        for (int i = 0; i < str.length; i++) {
            System.out.print(str[i]);
        }
    }

}

Вихід:

гострик


8

Як зазначають інші, кращим способом є використання:

new StringBuilder(hi).reverse().toString()

Але якщо ви хочете реалізувати це самостійно, я боюся, що решта відповідей має недоліки.

Причина полягає в тому, що Stringпредставляє список точок Unicode , кодованих у char[]масиві відповідно до кодування змінної довжини: UTF-16 .

Це означає, що деякі кодові точки використовують один елемент масиву (одна одиниця коду), а інші використовують два з них, тому можуть бути пари символів, які повинні розглядатися як одна одиниця (послідовні сурогати "високий" та "низький") .

public static String reverseString(String s) {
    char[] chars = new char[s.length()];
    boolean twoCharCodepoint = false;
    for (int i = 0; i < s.length(); i++) {
        chars[s.length() - 1 - i] = s.charAt(i);
        if (twoCharCodepoint) {
            swap(chars, s.length() - 1 - i, s.length() - i);
        }
        twoCharCodepoint = !Character.isBmpCodePoint(s.codePointAt(i));
    }
    return new String(chars);
}

private static void swap(char[] array, int i, int j) {
    char temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

public static void main(String[] args) throws Exception {
    FileOutputStream fos = new FileOutputStream("C:/temp/reverse-string.txt");
    StringBuilder sb = new StringBuilder("Linear B Syllable B008 A: ");
    sb.appendCodePoint(65536); //http://unicode-table.com/es/#10000
    sb.append(".");
    fos.write(sb.toString().getBytes("UTF-16"));
    fos.write("\n".getBytes("UTF-16"));
    fos.write(reverseString(sb.toString()).getBytes("UTF-16"));
}

Хороше рішення, бракує лише частини, - це тепер поєднання діакритики :-D
Рене,

6

Дуже просто в мінімальному коді рядків

public class ReverseString {
    public static void main(String[] args) {
        String s1 = "neelendra";
        for(int i=s1.length()-1;i>=0;i--)
            {
                System.out.print(s1.charAt(i));
            }
    }
}

Я збирався це зараз написати .. Знайшов, ви це вже написали!
Jency

4

Це зробило для мене трюк

public static void main(String[] args) {

    String text = "abcdefghijklmnopqrstuvwxyz";

    for (int i = (text.length() - 1); i >= 0; i--) {
        System.out.print(text.charAt(i));
    }
}

4

1. Використання масиву символів:

public String reverseString(String inputString) {
    char[] inputStringArray = inputString.toCharArray();
    String reverseString = "";
    for (int i = inputStringArray.length - 1; i >= 0; i--) {
        reverseString += inputStringArray[i];
    }
    return reverseString;
}

2. Використання StringBuilder:

public String reverseString(String inputString) {
    StringBuilder stringBuilder = new StringBuilder(inputString);
    stringBuilder = stringBuilder.reverse();
    return stringBuilder.toString();
}

АБО

return new StringBuilder(inputString).reverse().toString();

3
System.out.print("Please enter your name: ");
String name = keyboard.nextLine();

String reverse = new StringBuffer(name).reverse().toString();
String rev = reverse.toLowerCase();
System.out.println(rev);

Я використовував цей метод, щоб повернути імена назад і в малі регістри.


2
    public String reverse(String s) {

        String reversedString = "";
        for(int i=s.length(); i>0; i--) {
            reversedString += s.charAt(i-1);
        }   

        return reversedString;
    }

Знову сурогатні пари таким чином зіпсуються.
HyperNeutrino

@JamesSmith Ви могли б розширити цю проблему?
Дом Шахбазі

1
Деякі символи unicode складаються з двох символів; якщо ці двоє переключити, рядок пошкоджена. Крім того, одна часто не помічена помилка - це регулярний вираз.
HyperNeutrino

2

Один із природних способів змінити а String- використовувати a StringTokenizerі стек. Stackце клас, який реалізує простий у використанні стек об'єктів "останній-в-перший" (LIFO).

String s = "Hello My name is Sufiyan";

Покладіть його в стопку спереду

Stack<String> myStack = new Stack<>();
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
     myStack.push(st.nextToken());
}

Роздрукуйте стек назад

System.out.print('"' + s + '"' + " backwards by word is:\n\t\"");
while (!myStack.empty()) {
  System.out.print(myStack.pop());
  System.out.print(' ');
}

System.out.println('"');


2

Все вищезазначене рішення занадто добре, але тут я створюю зворотний рядок, використовуючи рекурсивне програмування.

Це корисно для того, хто шукає рекурсивний спосіб робити зворотний рядок.

public class ReversString {

public static void main(String args[]) {
    char s[] = "Dhiral Pandya".toCharArray();
    String r = new String(reverse(0, s));
    System.out.println(r);
}

public static char[] reverse(int i, char source[]) {

    if (source.length / 2 == i) {
        return source;
    }

    char t = source[i];
    source[i] = source[source.length - 1 - i];
    source[source.length - 1 - i] = t;

    i++;
    return reverse(i, source);

}

}

2

Порядок:

Ми можемо використовувати split () для розділення рядка. Потім використовуємо зворотний цикл і додаємо символи.


Фрагмент коду:

class test
{
  public static void main(String args[]) 
  {
      String str = "world";
      String[] split= str.split("");

      String revers = "";
      for (int i = split.length-1; i>=0; i--)
      {
        revers += split[i];
      }
      System.out.printf("%s", revers);
   }  
}

 //output : dlrow


1

public string stringWords (Строкові s) {

    String reversedWords = "";

    if(s.length()<=0) {
        return reversedWords;
    }else if(s.length() == 1){
        if(s == " "){
            return "";
        }
        return s;
    }

    char arr[] = s.toCharArray();
    int j = arr.length-1;
    while(j >= 0 ){
        if( arr[j] == ' '){
            reversedWords+=arr[j];
        }else{
            String temp="";
            while(j>=0 && arr[j] != ' '){
                temp+=arr[j];
                j--;
            }
            j++;
            temp = reverseWord(temp);
            reversedWords+=temp;
        }
        j--;

    }

    String[] chk = reversedWords.split(" ");

    if(chk == null || chk.length == 0){
        return "";
    }

    return reversedWords;



}

public String reverseWord(String s){

    char[] arr = s.toCharArray();

    for(int i=0,j=arr.length-1;i<=j;i++,j--){
        char tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    return String.valueOf(arr);

}

1

Ви також можете спробувати це:

public class StringReverse {
    public static void main(String[] args) {
        String str = "Dogs hates cats";
        StringBuffer sb = new StringBuffer(str);
        System.out.println(sb.reverse());
    }
}

1
існує багато методів повернення string.this є одним з них, використовуючи клас stringbuffer java.accepted відповіді, використовуючи клас diff для зворотного перегляду, який недоступний у старій версії JDK.
Анураг Гоел

1
public void reverString(){
System.out.println("Enter value");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
 try{

  String str=br.readLine();
  char[] charArray=str.toCharArray();
  for(int i=charArray.length-1; i>=0; i--){
   System.out.println(charArray[i]);
  }
  }
   catch(IOException ex){
  }

1

рекурсія:

 public String stringReverse(String string) {
    if (string == null || string.length() == 0) {
        return string;
    }
    return stringReverse(string.substring(1)) + string.charAt(0);
 }

1

Задля розваги..:)

Algorithm (str,len)
char reversedStr[] =new reversedStr[len]

Пройдіть i від 0 до len / 2, а потім

reversedStr[i]=str[len-1-i]  
reversedStr[len-1=i]=str[i]
return reversedStr;

Складність часу: O (n)

Складність простору: O (n)

public class Reverse {
    static char reversedStr[];

    public static void main(String[] args) {
        System.out.println(reversestr("jatin"));
    }


    private static String reversestr(String str) {
        int strlen = str.length();
        reversedStr = new char[strlen];

        for (int i = 0; i <= strlen / 2; i++) {
            reversedStr[i] = str.charAt(strlen - 1 - i);
            reversedStr[strlen - 1 - i] = str.charAt(i);

        }
        return new String(reversedStr);
    }

}

1
public static String revString(String str){
    char[] revCharArr = str.toCharArray();
    for (int i=0; i< str.length()/2; i++){
        char f = revCharArr[i];
        char l = revCharArr[str.length()-i-1];
        revCharArr[i] = l;
        revCharArr[str.length()-i-1] = f;
    }
    String revStr = new String(revCharArr);
    return revStr;
}

1
    public static void reverseString(String s){
        System.out.println("---------");
        for(int i=s.length()-1; i>=0;i--){
            System.out.print(s.charAt(i));    
        }
        System.out.println(); 

    }

Це просто виводить char рядка по одному. А також його не можна використовувати ніде в програмі. Набагато краще створити змінну String, вставити "char" по черзі в рядок, а потім повернути рядок.
Zombie Chibi XD

1
    //Solution #1 -- Using array and charAt()
    String name = "reverse"; //String to reverse
    Character[] nameChar =  new Character[name.length()]; // Declaring a character array with length as length of the String which you want to reverse.
    for(int i=0;i<name.length();i++)// this will loop you through the String
    nameChar[i]=name.charAt(name.length()-1-i);// Using built in charAt() we can fetch the character at a given index. 
    for(char nam:nameChar)// Just to print the above nameChar character Array using an enhanced for loop
    System.out.print(nam);


    //Solution #2 - Using StringBuffer and reverse ().
    StringBuffer reverseString = new StringBuffer("reverse");
    System.out.println(reverseString.reverse()); //reverse () Causes the character sequence to be replaced by the reverse of the sequence.

@Dharman дякую за відповідь. додано пояснення та ще одне рішення.
абхі

0
package logicprogram;
import java.io.*;

public class Strinrevers {
public static void main(String args[])throws IOException
{
    BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    System.out.println("enter data");
    String data=br.readLine();
    System.out.println(data);
    String str="";
    char cha[]=data.toCharArray();

    int l=data.length();
    int k=l-1;
    System.out.println(l);


    for(int i=0;k>=i;k--)
    {

        str+=cha[k];


    }
    //String text=String.valueOf(ch);
    System.out.println(str);

}

}

0
import java.util.Scanner;

public class Test {

    public static void main(String[] args){
        Scanner input = new Scanner (System.in);
        String word = input.next();
        String reverse = "";
        for(int i=word.length()-1; i>=0; i--)
            reverse += word.charAt(i);
        System.out.println(reverse);        
    }
}

Якщо ви хочете використовувати простий для циклу!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.