Як записатися Reverse рядок у Java за допомогою рекурсії

⚡ Розумний підсумок

Revзаміна рядка в Java Рекурсія працює шляхом видалення першого символу, звернення залишків на зворотне місце та додавання цього першого символу в кінець. Порожній рядок зупиняє виклики та розмотує стек.

  • 🔘 Базовий випадок: Метод повертає значення одразу, коли isEmpty() повідомляє, що нічого не залишилося для зворотного відображення.
  • ☑️ Рекурсивний крок: substring(1) видаляє перший символ, а charAt(0) поміщає його назад після зворотного залишку.
  • незмінність: Кожен виклик створює новий об'єкт String, оскільки Java Рядок ніколи не можна редагувати на місці.
  • 🧪 Trace: Guru99 стає 99uruG після семи викликів, по одному для кожного символу плюс порожній базовий регістр.
  • 🛠️ Швидші варіанти: StringBuilder.reverse() та двовказівникова операція swap over toCharArray() завершуються за один прохід.
  • 📌 Вартість: Рекурсія з substring() виконується за квадратичний час і містить один стековий кадр на символ.

Java програма, яка рекурсивно виконує рядок у зворотному порядку

У цьому прикладі програми ми перевернемо рядок, введений користувачем.

Ми створимо функцію для звернення рядка. Later Ми будемо викликати це рекурсивно, доки всі символи не будуть перевернуті. Рекурсія підходить для цієї задачі, оскільки обернутий рядок — це просто обернутий хвіст рядка з початковим першим символом, застряглим на кінці, що є тією ж задачею, але на один символ менше.

Написати Java Програма для Reverse рядок

Клас нижче оголошує вхідні дані в main(), передає їх до reverseString() та друкує те, що повертається. Два виклики println() всередині методу роблять кожен рекурсивний крок видимим у консолі.

package com.guru99;
 
public class ReverseString {
 
	public static void main(String[] args) {
 
 
		String myStr = "Guru99";
 
 
		//create Method and pass and input parameter string 
		String reversed = reverseString(myStr);
		System.out.println("The reversed string is: " + reversed);
		
	}
 
 
	//Method take string parameter and check string is empty or not
	public static String reverseString(String myStr)
	{
		if (myStr.isEmpty()){
		 System.out.println("String in now Empty");	
		 return myStr;
		}
		//Calling Function Recursively
		System.out.println("String to be passed in Recursive Function: "+myStr.substring(1));
		return reverseString(myStr.substring(1)) + myStr.charAt(0);
	}
 
}

Code вихід:

Кожен рядок виводу є одним рекурсивним викликом. Хвіст, виведений у кожному рядку, на один символ коротший за рядок над ним, а останній рядок показує зворотний результат.

String to be passed in Recursive Function: uru99
String to be passed in Recursive Function: ru99
String to be passed in Recursive Function: u99
String to be passed in Recursive Function: 99
String to be passed in Recursive Function: 9
String to be passed in Recursive Function: 
String in now Empty
The reversed string is: 99uruG

Як рекурсивний Reversal працює крок за кроком

Два рядки містять весь метод. Базовий випадок, if (myStr.isEmpty()), вказує на місце, де рекурсія має зупинитися. Рекурсивний рядок return reverseString(myStr.substring(1)) + myStr.charAt(0) розділяє роботу на дві частини: substring(1) — це все після першого символу, а charAt(0) — це цей перший символ, доданий до нього. після обернений залишок.

Tracвведення Guru99 чітко визначає порядок. Java перед кожним викликом надсилає один кадр, перш ніж відбудеться будь-яке об'єднання:

викликmyStrПереведено на наступний викликВираз очікує завершення
1Guru99уру99зворотнийРядок(“uru99”) + G
2уру99ru99зворотнийРядок(“ru99”) + u
3ru99u99зворотнийРядок(“u99”) + r
4u9999зворотнийРядок("99") + u
5999зворотнийРядок("9") + 9
69(порожній)зворотнийРядок("") + 9
7(порожній)базовий сценарій досягнутоповертає порожній рядок

Потім стек розмотується знизу вгору, і кожен кадр додає свій збережений символ: порожній рядок стає 9, потім 99, потім 99u, 99ur, 99uru і, нарешті, 99uruG. Оскільки Java Рядки незмінні, жодне з цих проміжних значень не перезаписує попереднє — кожне об'єднання виділяє новий об'єкт String.

Варто згадати дві деталі у виводі консолі. Шостий рядок закінчується нічим після двокрапки, оскільки substring(1) для односимвольного рядка повертає порожній рядок, а не null. Наступне повідомлення в оригінальній програмі має вигляд «String in now Empty» (Рядок тепер порожній); це формулювання є друкарською помилкою для «String is now empty» (Рядок тепер порожній) і залишилося недоторканим, тому код і наведений вище вивід все ще збігаються рядок за рядком.

Інші способи Reverse рядок у Java

Рекурсія — це найзрозуміліший спосіб побачити Зворотне виконання відбувається, але це рідко відбувається у виробничому коді. Три альтернативи охоплюють майже кожен реальний випадок.

1. StringBuilder.reverse() є найкоротшим і найшвидшим. Клас має вбудований метод reverse(), тому все завдання поміщається в один рядок:

String reversed = new StringBuilder(myStr).reverse().toString();

2. Цикл for з charAt() переглядає рядок у зворотному порядку від останнього індексу до нуля. Інтерв'юери часто запитують цю версію, оскільки вона показує логіку, а не делегує її:

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

3. Двовказівковий обмін значеннями методом toCharArray() перетворює рядок на масив символів, потім міняє крайні символи всередину, доки вказівники не зустрінуться посередині:

char[] chars = myStr.toCharArray();
int left = 0;
int right = chars.length - 1;
while (left < right) {
    char temp = chars[left];
    chars[left] = chars[right];
    chars[right] = temp;
    left++;
    right--;
}
String reversed = new String(chars);

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

Часова та просторова складність кожного підходу

Чотири версії коштують не однаково. Обидва квадратичні записи нижче мають одну спільну причину: вони створюють абсолютно новий рядок на кожному кроці, а копіювання n символів n разів — це n квадратичних операцій.

ПідхідTimeДодатковий простірЧому
Рекурсія з підрядком()O (n²)O (n²)substring() копіює решту символів під час кожного виклику, і один стековий кадр зберігається на кожен символ.
цикл for з charAt() та +O (n²)O (n²)Кожне об'єднання виділяє новий рядок (String) та копіює все, що зібрано на даний момент.
StringBuilder.reverse()О (п)О (п)Один змінний буфер, один прохід та сурогатні пари зберігаються недоторканими
Два вказівники на toCharArray()О (п)О (п)Одна копія масиву, потім n/2 обмінів без подальшого розподілу

Виберіть рекурсивну версію, щоб вивчити або продемонструвати, як поводиться стек викликів, версію з символьним масивом, коли інтерв'юер запитує логіку вручну, та StringBuilder.reverse() у будь-якому постачальнику. Той самий компроміс між навчальним рішенням та рішенням для виробництва проявляється у класичних вправах, від сортування бульбашками і Серія Фібоначчі до перевірки простих чисел; кожен з них вартий практики Java в обидва боки.

Поширені запитання

Рядкові об'єкти є незмінними, тому символи всередині них ніколи не можуть змінитися після створення. Тому кожне перетворення створює новий об'єкт. Використовуйте StringBuilder або масив символів, коли символи потрібно змінювати без виділення нового рядка на кожному кроці.

Перший виклик isEmpty() викидає виняток NullPointerException, оскільки метод викликається без жодного значення. Захистіть точку входу перевіркою на null, яка повертає null, або викидає IllegalArgumentException перед початком будь-якої рекурсії.

Ненадійно. charAt() працює з 16-бітними одиницями коду, тому символ, що зберігається як сурогатна пара, розділяється, і зворотний текст показує квадрати заміни. StringBuilder.reverse() зберігає сурогатні пари разом, що робить його безпечнішим вибором для тексту Unicode.

StringBuilder, майже у кожному випадку. Обидва надають той самий метод reverse(), але StringBuffer синхронізує кожен дзвінок, що призводить до зниження швидкості. Виберіть рядокBuffer лише тоді, коли один буфер справді спільно використовується між потоками.

Розділіть речення на пробіли за допомогою split(” “), потім пройдіться по результуючому масиву від останнього індексу до першого, додаючи кожне слово до StringBuilder. Символи всередині кожного слова залишаються в початковому порядку.

Один стековий фрейм використовується на один символ, тому типовим є кілька тисяч символів, перш ніж з'явиться StackOverflowError. Точне обмеження залежить від розміру стеку потоку JVM. Будь-яка ітеративна версія повністю уникає стелі.

Помічник зі штучним інтелектом може зчитувати стек tracе., вказати на відсутній або недосяжний базовий випадок та пояснити порядок, у якому фрейми розгортаються. Також розроблено тести на крайні випадки для порожніх, односимвольних та нульових вхідних даних. Перевірити міркування на реальному прогоні.

Так. Copilot зазвичай завершує цілий зворотний метод лише з сигнатури, часто пропонуючи форму StringBuilder першою. Перевірте базовий випадок та складність, оскільки найкоротша пропозиція не завжди є версією, яку запитує вправа.

Підсумуйте цей пост за допомогою: