πώς να Reverse μια συμβολοσειρά Java χρησιμοποιώντας το Recursion

⚡ Έξυπνη Σύνοψη

Revεισαγωγή μιας συμβολοσειράς Java με την αναδρομή, η μέθοδος λειτουργεί αφαιρώντας τον πρώτο χαρακτήρα, αντιστρέφοντας ό,τι απομένει και προσθέτοντας αυτόν τον πρώτο χαρακτήρα στο τέλος. Μια κενή συμβολοσειρά σταματά τις κλήσεις και ξετυλίγει τη στοίβα.

  • 🔘 Βασική περίπτωση: Η μέθοδος επιστρέφει αμέσως όταν η isEmpty() αναφέρει ότι δεν έχει απομείνει τίποτα προς αντιστροφή.
  • ☑️ Επαναληπτικό βήμα: Η substring(1) αφαιρεί τον πρώτο χαρακτήρα και η charAt(0) τον επαναφέρει μετά το αντεστραμμένο υπόλοιπο.
  • Αμετάβλητο: Κάθε κλήση παράγει ένα νέο αντικείμενο String, επειδή ένα Java Δεν είναι δυνατή η επεξεργασία μιας συμβολοσειράς στη θέση της.
  • 🧪 Trace: GuruΤο 99 γίνεται 99uruG μετά από επτά κλήσεις, μία για κάθε χαρακτήρα συν την κενή βασική περίπτωση.
  • Ταχύτερες επιλογές: Η StringBuilder.reverse() και μια εναλλαγή δύο δεικτών πάνω από την 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εισαγωγή GuruΤο 99 καθιστά σαφή την τάξη. Java ωθεί ένα πλαίσιο για κάθε κλήση πριν συμβεί οποιαδήποτε συνένωση:

ΚαλέστεmyStrΠέρασε στην επόμενη κλήσηΈκφραση που περιμένει να τελειώσει
1Guru99uru99reverseString(“uru99”) + G
2uru99ru99reverseString(“ru99”) + u
3ru99u99reverseString(“u99”) + r
4u9999reverseString("99") + u
5999reverseString("9") + 9
69(αδειάζω)reverseString("") + 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 και, στη συνέχεια, ανταλλάσσει τους εξωτερικούς χαρακτήρες προς τα μέσα μέχρι οι δείκτες να συναντηθούν στη μέση:

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 τετραγωνική εργασία.

ΠροσέγγισηΧρόνοςΕπιπλέον χώροςΓιατί
Αναδρομή με substring()O(n²)O(n²)Η substring() αντιγράφει τους υπόλοιπους χαρακτήρες σε κάθε κλήση και ένα πλαίσιο στοίβας διατηρείται ανά χαρακτήρα.
βρόχος for με charAt() και +O(n²)O(n²)Κάθε συνένωση εκχωρεί μια νέα συμβολοσειρά και αντιγράφει όλα όσα έχουν συγκεντρωθεί μέχρι στιγμής
StringBuilder.reverse()O (n)O (n)Ένα μεταβλητό buffer, ένα πέρασμα και τα ζεύγη υποκατάστατων διατηρούνται άθικτα
Δύο δείκτες πάνω από τοCharArray()O (n)O (n)Ένα αντίγραφο πίνακα, έπειτα n/2 εναλλαγές χωρίς περαιτέρω κατανομή

Επιλέξτε την αναδρομική έκδοση για να μάθετε ή να δείξετε πώς συμπεριφέρεται η στοίβα κλήσεων, την έκδοση char-array όταν ένας συνεντευξιαστής ζητά τη λογική χειροκίνητα και την StringBuilder.reverse() σε οτιδήποτε αποστέλλεται. Η ίδια αντιστάθμιση μεταξύ μιας λύσης διδασκαλίας και μιας λύσης παραγωγής εμφανίζεται σε όλες τις κλασικές ασκήσεις, από τύπος φυσαλίδων και την Σειρά Fibonacci προς την έλεγχοι πρώτων αριθμών; αξίζει να εξασκηθείτε σε κάθε ένα Java και προς τους δύο τρόπους.

Συχνές Ερωτήσεις

Τα αντικείμενα συμβολοσειράς είναι αμετάβλητα, επομένως οι χαρακτήρες μέσα σε ένα δεν μπορούν ποτέ να αλλάξουν μετά τη δημιουργία τους. Κάθε αντιστροφή επομένως δημιουργεί ένα νέο αντικείμενο. Χρησιμοποιήστε το StringBuilder ή έναν πίνακα χαρακτήρων όταν οι χαρακτήρες πρέπει να τροποποιηθούν χωρίς να εκχωρηθεί ένα νέο συμβολοσειρά σε κάθε βήμα.

Η πρώτη κλήση της isEmpty() ρίχνει μια NullPointerException, επειδή η μέθοδος καλείται σε τίποτα. Προστατέψτε το σημείο εισόδου με έναν έλεγχο null που επιστρέφει null ή ρίχνει IllegalArgumentException πριν ξεκινήσει οποιαδήποτε αναδρομή.

Δεν είναι αξιόπιστη. Η συνάρτηση charAt() λειτουργεί σε μονάδες κώδικα 16-bit, επομένως ένας χαρακτήρας που αποθηκεύεται ως ζεύγος υποκατάστατων διαιρείται και το αντίστροφο κείμενο εμφανίζει τετράγωνα αντικατάστασης. Η συνάρτηση StringBuilder.reverse() διατηρεί τα ζεύγη υποκατάστατων μαζί, γεγονός που την καθιστά ασφαλέστερη επιλογή για κείμενο Unicode.

StringBuilder, σχεδόν σε κάθε περίπτωση. Και οι δύο εκθέτουν την ίδια μέθοδο reverse(), αλλά το StringBuffer συγχρονίζει κάθε κλήση, κάτι που κοστίζει ταχύτητα. Επιλέξτε Σειρά χαρακτήρωνBuffer μόνο όταν ένα buffer είναι πραγματικά κοινόχρηστο μεταξύ των νημάτων.

Χωρίστε την πρόταση σε κενό διάστημα με τη συνάρτηση split(” “) και, στη συνέχεια, μετακινήστε τον προκύπτοντα πίνακα από τον τελευταίο δείκτη στον πρώτο, προσθέτοντας κάθε λέξη σε ένα StringBuilder. Οι χαρακτήρες μέσα σε κάθε λέξη παραμένουν στην αρχική τους σειρά.

Χρησιμοποιείται ένα πλαίσιο στοίβας ανά χαρακτήρα, επομένως μερικές χιλιάδες χαρακτήρες είναι τυπικοί πριν εμφανιστεί ένα StackOverflowError. Το ακριβές όριο εξαρτάται από το μέγεθος της στοίβας νημάτων JVM. Οποιαδήποτε επαναληπτική έκδοση αποφεύγει εντελώς το ανώτατο όριο.

Ένας βοηθός τεχνητής νοημοσύνης μπορεί να διαβάσει μια στοίβα tracε., υποδεικνύει μια βασική περίπτωση που λείπει ή είναι μη προσβάσιμη και εξηγεί τη σειρά με την οποία ξετυλίγονται τα πλαίσια. Επίσης, συντάσσει δοκιμές edge-case για κενή, μονού χαρακτήρα και μηδενική είσοδο. Επαληθεύει τη συλλογιστική σε σχέση με μια πραγματική εκτέλεση.

Ναί. Δεύτερος πιλότος συνήθως ολοκληρώνει μια εντελώς αντίστροφη μέθοδο μόνο από την υπογραφή, συχνά προσφέροντας πρώτα τη φόρμα StringBuilder. Ελέγξτε την βασική περίπτωση και την πολυπλοκότητα, επειδή η συντομότερη πρόταση δεν είναι πάντα η έκδοση που ζητά μια άσκηση.

Συνοψίστε αυτήν την ανάρτηση με: