Hogyan Reverse egy karakterlánc Java Rekurzió segítségével

⚡ Okos összefoglaló

Revbedug egy húrt Java A rekurzió úgy működik, hogy lehúzzuk az első karaktert, megfordítjuk a maradékot, és az első karaktert a végére fűzzük. Egy üres karakterlánc leállítja a hívásokat és bontja a verem tartalmát.

  • 🔘 Alap helyzet: A metódus azonnal visszatér, amikor az isEmpty() azt jelzi, hogy nincs mit visszafordítani.
  • ☑️ Rekurzív lépés: A substring(1) eltávolítja az első karaktert, a charAt(0) pedig visszahelyezi azt a megfordított maradék után.
  • Állandóság: Minden hívás egy új String objektumot hoz létre, mivel egy Java A karakterláncot soha nem lehet helyben szerkeszteni.
  • 🧪 Trace: GuruA 99 hét hívás után 99uruG lesz, minden karakterhez egy, plusz az üres alapesethez.
  • 🇧🇷 Gyorsabb lehetőségek: A StringBuilder.reverse() és a kétmutatós csere a toCharArray() függvényre egyetlen menetben fejeződik be.
  • 📌 Költség: A substring() függvény rekurziója kvadratikus időben fut, és karakterenként egy veremképkockát tárol.

Java program, amely rekurzív metódussal megfordít egy karakterláncot

Ebben a példaprogramban megfordítjuk a felhasználó által beírt karakterláncot.

Létrehozunk egy függvényt a karakterlánc megfordításához. Later Rekurzívan fogjuk hívni, amíg az összes karakter fel nem cserélődik. A rekurzió megfelel ennek a problémának, mert egy fordított karakterlánc egyszerűen a karakterlánc fordított vége, amelynek eredeti első karaktere a végére ragadt, ami ugyanaz a probléma eggyel kisebb karakterrel.

Írj egy Java Program a Reverse Húr

Az alábbi osztály deklarálja a bemenetet a main() függvényben, átadja azt a reverseString() függvénynek, és kinyomtatja a visszaadott értéket. A metóduson belüli két println() hívás minden rekurzív lépést láthatóvá tesz a konzolon.

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 output:

A kimenet minden sora egy rekurzív hívás. Minden sorban a vége egy karakterrel rövidebb, mint a felette lévő sor, és az utolsó sor a fordított eredményt mutatja.

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

Hogyan működik a rekurzív Reversal működik lépésről lépésre

Két sor tartalmazza a teljes metódust. Az alapeset, ha (myStr.isEmpty()), megadja a rekurzió leállításának helyét. A rekurzív sor, return reverseString(myStr.substring(1)) + myStr.charAt(0), kettéosztja a munkát: a substring(1) az első karakter utáni összes karakter, a charAt(0) pedig az első karakter, hozzáfűzve. után a fordított maradék.

Traca bemenet GuruA 99-es egyértelművé teszi a sorrendet. Java minden hívásnál egy keretet küld, mielőtt bármilyen összefűzés megtörténne:

HívásmyStrÁtadva a következő hívásnakKifejezés befejezésre vár
1Guru99uru99fordított karakterlánc(„uru99”) + G
2uru99ru99fordított karakterlánc(„ru99”) + u
3ru99u99fordított karakterlánc(„u99”) + r
4u9999fordított karakterlánc(„99”) + u
5999fordított karakterlánc(„9”) + 9
69(üres)fordított karakterlánc("") + 9
7(üres)alapeset elérveüres karakterláncot ad vissza

A verem ezután alulról felfelé letekerődik, és minden keret hozzáfűzi a mentett karakterét: az üres karakterláncból 9, majd 99, majd 99u, 99ur, 99uru és végül 99uruG. Mert Java A karakterláncok megváltoztathatatlanok, ezek közül a köztes értékek közül egyik sem írja felül az előzőt – minden összefűzés egy új String objektumot foglal le.

A konzol kimenetének két részletét érdemes megnevezni. A hatodik sor a kettőspont után üresen végződik, mivel az egy karakteres karakterláncon a substring(1) üres karakterláncot ad vissza null helyett. Az ezt követő üzenet az eredeti programban a következő: „A karakterlánc most üres”; a megfogalmazás elírás a „Karakterlánc most üres” helyett, és érintetlen maradt, így a kód és a fenti kimenet továbbra is sorról sorra megegyezik.

Egyéb módok Reverse egy karakterlánc Java

A rekurzió a legegyértelműbb módja annak, hogy lát A megfordulás megtörténhet, de ritkán úgy, ahogy a gyártási kód teszi. Három alternatíva lefedi szinte minden valós esetet.

1. StringBuilder.reverse() a legrövidebb és leggyorsabb. Az osztály beépített reverse() metódust tartalmaz, így a teljes feladat elfér egy sorban:

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

2. Egy for ciklus charAt() függvénnyel visszafelé halad a karakterláncban az utolsó indextől a nulláig. Az interjúztatók gyakran kérik ezt a verziót, mert ez a logikát mutatja a delegálás helyett:

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

3. Két mutatós csere a CharArray() függvényre karakterláncot char tömbbé alakít, majd a legkülső karaktereket befelé cseréli, amíg a mutatók középen nem találkoznak:

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

Ugyanez a tömbtechnika megfordít egy numerikus sorozatot vagy bármely más rendezett gyűjteményt, ezért jelenik meg a Java sor olyan gyakran végez gyakorlatokat, mint a vonós gyakorlatokban.

Az egyes megközelítések időbeli és térbeli komplexitása

A négy változat nem ugyanannyiba kerül. Az alábbi mindkét másodfokú bejegyzésnek van egy közös oka: minden lépésben egy vadonatúj karakterláncot hoznak létre, és n karakter n-szeres másolása n négyzetes munka.

MegközelítésTimeExtra helyMiért
Rekurzió a substring() függvénnyelO(n²)O(n²)A substring() minden híváskor lemásolja a fennmaradó karaktereket, és karakterenként egy veremkeretet tárol.
for ciklus charAt() és + függvényekkelO(n²)O(n²)Minden összefűzés egy új karakterláncot foglal le, és lemásolja az eddig összegyűjtött összes adatot.
StringBuilder.reverse()O (n)O (n)Egy módosítható puffer, egy menetes és helyettesítő párok maradnak érintetlenül
Két mutató a CharArray() függvény felettO (n)O (n)Egy tömbmásolás, majd n/2 csere további lefoglalás nélkül

Válaszd a rekurzív verziót a hívásverem viselkedésének tanulásához vagy bemutatásához, a karaktertömbös verziót, amikor a kérdező kézzel kérdezi le a logikát, és a StringBuilder.reverse()-t minden olyan esetben, ami gyárilag telepítve van. Ugyanez a kompromisszum jelenik meg a tanítási és az éles megoldások között a klasszikus gyakorlatokban is, a ...-tól ...-ig. buborékfajta és a Fibonacci sorozat nak nek prímszám-ellenőrzésekmindegyikben érdemes gyakorolni Java mindkét irányban.

GYIK

A karakterlánc objektumok megváltoztathatatlanok, tehát a bennük lévő karakterek a létrehozás után soha nem változhatnak. Minden megfordítás tehát egy új objektumot hoz létre. Használj StringBuildert vagy char tömböt, ha a karaktereket úgy kell módosítani, hogy minden lépésben új karakterláncot nem kell lefoglalni.

Az isEmpty() első hívása NullPointerException kivételt dob, mivel a metódus a semmire hivatkozik. A belépési pontot null ellenőrzéssel védjük, amely null értéket ad vissza, vagy IllegalArgumentException kivételt dob, mielőtt bármilyen rekurzió megkezdődne.

Nem megbízható. A charAt() 16 bites kódegységeken működik, így a helyettesítő párként tárolt karaktereket szétválasztja a rendszer, és a fordított szöveg helyettesítő négyzeteket jelenít meg. A StringBuilder.reverse() egyben tartja a helyettesítő párokat, ami biztonságosabb választássá teszi Unicode szövegekhez.

A StringBuilder szinte minden esetben. Mindkettő ugyanazt a reverse() metódust használja, de a StringBuffer minden hívást szinkronizál, ami sebességcsökkenést okoz. Válassza a Karakterlánc lehetőséget.Buffer csak akkor, ha egy puffer valóban megosztott a szálak között.

A mondatot szóközökkel kettéosztjuk a split(” “) paranccsal, majd a kapott tömböt az utolsó indextől az elsőig haladva végigjárjuk, minden szót egy StringBuilderhez fűzve. Az egyes szavakon belüli karakterek az eredeti sorrendjükben maradnak.

Karakterenként egy veremkeretet használunk, így jellemzően néhány ezer karakter után jelenik meg a StackOverflowError hiba. A pontos korlát a JVM szálverem méretétől függ. Bármely iteratív verzió teljesen elkerüli a felső határt.

Egy mesterséges intelligencia asszisztens képes olvasni egy köteget trace, mutasson rá egy hiányzó vagy elérhetetlen alapesetre, és magyarázza el a képkockák letekercselődésének sorrendjét. Emellett szélső eseteket is tesztel üres, egykarakteres és null bemenet esetén. Ellenőrizze az érvelést egy valós futtatással szemben.

Igen. Másodpilóta általában egy teljes fordított metódust hajt végre pusztán az aláírásból kiindulva, gyakran először a StringBuilder űrlapot kínálva fel. Ellenőrizd az alapesetet és a bonyolultságot, mert a legrövidebb javaslat nem mindig az a verzió, amelyet egy gyakorlat kér.

Foglald össze ezt a bejegyzést a következőképpen: