jak na to Reverse řetězec v Java pomocí rekurze

⚡ Chytré shrnutí

Reversing řetězce v Java Rekurze funguje tak, že se oddělí první znak, zbývající znak se obrátí a tento první znak se připojí na konec. Prázdný řetězec zastaví volání a vrátí zpět zásobník.

  • 🔘 Základní případ: Metoda vrátí hodnotu okamžitě, když isEmpty() oznámí, že už nezbývá nic k vrácení.
  • ☑️ Rekurzivní krok: substring(1) odstraní první znak a charAt(0) ho vloží zpět za obrácený zbytek.
  • (Tj. Neměnnost: Každé volání vytvoří nový objekt typu String, protože Java Řetězec nelze nikdy upravovat na místě.
  • 🧪 Trace: GuruZ 99 se po sedmi voláních, jednom pro každý znak plus prázdný základní případ, stane 99uruG.
  • 🛠️ Rychlejší možnosti: Funkce StringBuilder.reverse() a dvoubodová swapovací operace typu toCharArray() se obě dokončí v jednom průchodu.
  • 📌 Cena: Rekurze s funkcí substring() běží v kvadratickém čase a uchovává jeden rámec zásobníku na znak.

Java program, který obrací řetězec pomocí rekurzivní metody

V tomto vzorovém programu obrátíme řetězec zadaný uživatelem.

Vytvoříme funkci pro obrácení řetězce. Later Budeme to volat rekurzivně, dokud nebudou všechny znaky obráceny. Rekurze se k tomuto problému hodí, protože obrácený řetězec je jednoduše obrácený konec řetězce s původním prvním znakem na konci, což je stejný problém, jen o jeden znak menší.

Napsat Java Programovat do Reverse Řetězec

Níže uvedená třída deklaruje vstup v main(), předá jej reverseString() a vypíše vrácenou hodnotu. Dvě volání println() uvnitř metody zviditelní každý rekurzivní krok v konzoli.

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 Výstup:

Každý řádek výstupu je jedno rekurzivní volání. Konec vytištěný na každém řádku je o jeden znak kratší než řádek nad ním a poslední řádek zobrazuje obrácený výsledek.

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

Jak rekurzivní Reversal funguje krok za krokem

Celou metodu nesou dva řádky. Základní případ, if (myStr.isEmpty()), určuje místo, kde se má rekurze zastavit. Rekurzivní řádek return reverseString(myStr.substring(1)) + myStr.charAt(0) rozděluje práci na dvě části: substring(1) je vše za prvním znakem a charAt(0) je tento první znak, připojený k po obrácený zbytek.

Traczadávání vstupu Guru99 objasňuje pořadí. Java vloží jeden rámec pro každé volání, než dojde k jakémukoli zřetězení:

volánímůjStrPředáno dalšímu hovoruVýraz čeká na dokončení
1Guru99uru99reverseString(„uru99“) + G
2uru99ru99reverseString(„ru99“) + u
3ru99u99reverseString(„u99“) + r
4u9999reverseString("99") + u
5999reverseString("9") + 9
69(prázdný)reverseString("") + 9
7(prázdný)dosaženo základního scénářevrací prázdný řetězec

Zásobník se poté odvíjí zdola nahoru a každý rámec připojuje svůj uložený znak: prázdný řetězec se stane 9, poté 99, pak 99u, 99ur, 99uru a nakonec 99uruG. Protože Java Řetězce jsou neměnné, žádná z těchto mezilehlých hodnot nepřepíše předchozí – každé zřetězení alokuje nový objekt String.

Za zmínku stojí dva detaily ve výstupu do konzole. Šestý řádek končí za dvojtečkou ničím, protože substring(1) u jednoznakového řetězce vrací prázdný řetězec, nikoli hodnotu null. Následující zpráva v původním programu zní „String in now Empty“ (Řetězec je nyní prázdný); formulace „String is now empty“ (Řetězec je nyní prázdný) je překlepem a zůstala nedotčena, takže kód a výstup výše se stále shodují řádek od řádku.

Jiné způsoby Reverse řetězec v Java

Rekurze je nejjasnější způsob, jak vidět K obrácení dochází, ale v produkčním kódu se to stává jen zřídka. Tři alternativy pokrývají téměř každý reálný případ.

1. StringBuilder.reverse() je nejkratší a nejrychlejší. Třída má vestavěnou metodu reverse(), takže se celá úloha vejde na jeden řádek:

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

2. Cyklus for s funkcí charAt() Prochází řetězec pozpátku od posledního indexu k nule. Tazatelé se často ptají na tuto verzi, protože ukazuje logiku, místo aby ji delegovala:

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

3. Dvouukazatelová swapovací funkce typu toCharArray() převede řetězec na pole znaků a poté vymění nejvzdálenější znaky směrem dovnitř, dokud se ukazatele nesetkají uprostřed:

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

Stejná technika pole obrací číselnou posloupnost nebo jakoukoli jinou uspořádanou kolekci, a proto se objevuje v Java řada cvičení stejně často jako u strunných nástrojů.

Časová a prostorová složitost každého přístupu

Čtyři verze se liší cenou. Oba níže uvedené kvadratické členy mají jeden společný důvod: v každém kroku vytvářejí zcela nový řetězec a kopírování n znaků n-krát je n na druhou.

PřístupČasExtra prostorProč
Rekurze s podřetězcem()O(n²)O(n²)substring() kopíruje zbývající znaky při každém volání a pro každý znak je uložen jeden rámec zásobníku.
smyčka for s charAt() a +O(n²)O(n²)Každé zřetězení alokuje nový řetězec a zkopíruje vše, co bylo dosud shromážděno.
StringBuilder.reverse()O (n)O (n)Jeden proměnlivý buffer, jeden průchod a náhradní páry zůstávají nedotčené.
Dva ukazatele na toCharArray()O (n)O (n)Jedna kopie pole, poté n/2 swapů bez další alokace

Vyberte rekurzivní verzi pro naučení nebo demonstraci chování zásobníku volání, verzi s polem znaků, když se tazatel ručně zeptá na logiku, a StringBuilder.reverse() v čemkoli, co je součástí dodávky. Stejný kompromis mezi výukovým řešením a produkčním řešením se projevuje v klasických cvičeních, od bublinové řazení a Fibonacciho řada na kontroly prvočíselkaždý z nich stojí za procvičení Java oběma směry.

Nejčastější dotazy

Objekty typu String jsou neměnné, takže znaky uvnitř nich se po vytvoření nikdy nemohou změnit. Každé obrácení proto vytvoří nový objekt. Pokud je nutné znaky upravit bez alokace nového řetězce v každém kroku, použijte StringBuilder nebo pole znaků.

První volání metody isEmpty() vyvolá výjimku NullPointerException, protože metoda je volána na nic. Chraňte vstupní bod kontrolou na hodnotu null, která vrací hodnotu null, nebo vyvolá výjimku IllegalArgumentException před zahájením jakékoli rekurze.

Nespolehlivě. charAt() funguje s 16bitovými kódovými jednotkami, takže znak uložený jako náhradní pár je rozdělen a obrácený text zobrazuje náhradní čtverce. StringBuilder.reverse() udržuje náhradní páry pohromadě, což z něj činí bezpečnější volbu pro text Unicode.

StringBuilder, téměř ve všech případech. Oba zpřístupňují stejnou metodu reverse(), ale StringBuffer synchronizuje každý hovor, což vede k nárůstu rychlosti. Vyberte řetězecBuffer pouze tehdy, když je jedna vyrovnávací paměť skutečně sdílena mezi vlákny.

Rozdělte větu podle bílých znaků pomocí funkce split(” “) a poté projděte výsledné pole od posledního indexu k prvnímu, přičemž každé slovo připojte k objektu StringBuilder. Znaky uvnitř každého slova zůstanou v původním pořadí.

Na jeden znak se používá jeden rámec zásobníku, takže typicky se před zobrazením chyby StackOverflowError objeví několik tisíc znaků. Přesný limit závisí na velikosti zásobníku vlákna JVM. Jakákoli iterativní verze se stropu zcela vyhne.

Asistent s umělou inteligencí dokáže číst zásobník trace. ukázat na chybějící nebo nedosažitelný základní případ a vysvětlit pořadí, ve kterém se rámce odvíjejí. Také navrhuje testy okrajových případů pro prázdné, jednoznakové a nulové vstupy. Ověřte zdůvodnění na reálném běhu.

Ano. Druhý pilot obvykle dokončí celou reverzní metodu pouze z signatury, často jako první nabízí formulář StringBuilder. Zkontrolujte základní případ a složitost, protože nejkratší návrh není vždy verzí, kterou cvičení požaduje.

Shrňte tento příspěvek takto: