Làm thế nào để Reverse một chuỗi trong Java sử dụng đệ quy

⚡ Tóm tắt thông minh

Revnối một chuỗi trong Java Phương thức đệ quy hoạt động bằng cách tách ký tự đầu tiên, đảo ngược phần còn lại và thêm ký tự đầu tiên đó vào cuối. Chuỗi rỗng sẽ dừng các lệnh gọi và giải phóng ngăn xếp.

  • 🔘 Trường hợp cơ bản: Phương thức này trả về ngay lập tức khi isEmpty() báo cáo rằng không còn gì để đảo ngược nữa.
  • ☑️ Bước đệ quy: substring(1) loại bỏ ký tự đầu tiên và charAt(0) đặt nó trở lại sau phần dư đảo ngược.
  • Tính bất biến: Mỗi lần gọi hàm sẽ tạo ra một đối tượng String mới, bởi vì... Java Chuỗi ký tự không thể được chỉnh sửa trực tiếp.
  • 🧪 Trace: Guru99 trở thành 99uruG sau bảy lần gọi, mỗi lần tương ứng với một ký tự cộng thêm trường hợp cơ sở rỗng.
  • 🛠️ Các lựa chọn nhanh hơn: Việc sử dụng StringBuilder.reverse() và hoán đổi hai con trỏ qua toCharArray() đều hoàn tất trong một lần xử lý duy nhất.
  • 📌 Chi phí: Đệ quy với hàm substring() chạy trong thời gian bậc hai và giữ một khung ngăn xếp cho mỗi ký tự.

Java Chương trình đảo ngược chuỗi bằng phương pháp đệ quy.

Trong chương trình ví dụ này, chúng tôi sẽ đảo ngược chuỗi do người dùng nhập.

Chúng ta sẽ tạo một hàm để đảo ngược một chuỗi. Later Chúng ta sẽ gọi hàm đệ quy cho đến khi tất cả các ký tự được đảo ngược. Đệ quy phù hợp với bài toán này vì một chuỗi đảo ngược chỉ đơn giản là phần đuôi đảo ngược của chuỗi với ký tự đầu tiên ban đầu được gắn vào cuối, tức là cùng một bài toán nhưng ngắn hơn một ký tự.

Viết thư cho Java Chương trình để Reverse Chuỗi

Lớp bên dưới khai báo đầu vào trong phương thức main(), chuyển nó cho phương thức reverseString() và in ra kết quả trả về. Hai lệnh println() bên trong phương thức này giúp hiển thị từng bước đệ quy trên bảng điều khiển.

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 Đầu ra:

Mỗi dòng trong kết quả đầu ra là một lời gọi đệ quy. Phần đuôi được in trên mỗi dòng ngắn hơn một ký tự so với dòng phía trên nó, và dòng cuối cùng hiển thị kết quả đảo ngược.

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

Cách thức đệ quy RevCác tác phẩm đa năng từng bước một

Toàn bộ phương thức được thực hiện bởi hai dòng lệnh. Trường hợp cơ sở, if (myStr.isEmpty()), cung cấp điểm dừng cho đệ quy. Dòng lệnh đệ quy, return reverseString(myStr.substring(1)) + myStr.charAt(0), chia công việc thành hai phần: substring(1) là tất cả những gì sau ký tự đầu tiên, và charAt(0) là ký tự đầu tiên đó, được nối thêm vào. sau khi phần dư đảo ngược.

Tracđầu vào GuruSố 99 làm rõ thứ tự. Java Mỗi lần gọi hàm sẽ đẩy một khung hình trước khi bất kỳ thao tác ghép nối nào diễn ra:

Gọi sốmyStrChuyển sang cuộc gọi tiếp theoBiểu cảm đang chờ hoàn thành
1Guru99uru99reverseString(“uru99”) + G
2uru99ru99reverseString(“ru99”) + u
3ru99u99reverseString(“u99”) + r
4u9999reverseString(“99”) + u
5999reverseString(“9”) + 9
69(trống)reverseString(“”) + 9
7(trống)đạt đến trường hợp cơ bảntrả về chuỗi rỗng

Sau đó, ngăn xếp được mở ra từ dưới lên trên, và mỗi khung hình sẽ thêm ký tự đã lưu của nó: chuỗi rỗng trở thành 9, sau đó là 99, rồi 99u, 99ur, 99uru, và cuối cùng là 99uru. 99uruG. Bởi vì Java Chuỗi ký tự là bất biến, không có giá trị trung gian nào ghi đè lên giá trị trước đó — mỗi phép nối chuỗi đều tạo ra một đối tượng String mới.

Có hai chi tiết trong đầu ra của bảng điều khiển đáng được đề cập. Dòng thứ sáu kết thúc mà không có gì sau dấu hai chấm, bởi vì hàm substring(1) trên một chuỗi một ký tự trả về chuỗi rỗng thay vì null. Thông báo tiếp theo có nội dung “String in now Empty” trong chương trình gốc; cách diễn đạt này là lỗi đánh máy của “String is now empty” và đã được giữ nguyên để mã và đầu ra ở trên vẫn khớp từng dòng.

Những cách khác để Reverse một chuỗi trong Java

Đệ quy là cách rõ ràng nhất để xem Việc đảo ngược có thể xảy ra, nhưng hiếm khi đó là cách mã sản xuất thực hiện. Ba phương án thay thế bao gồm hầu hết mọi trường hợp thực tế.

1. StringBuilder.reverse() Đây là cách ngắn nhất và nhanh nhất. Lớp này có sẵn phương thức `reverse()`, vì vậy toàn bộ công việc chỉ cần gói gọn trong một dòng lệnh:

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

2. Vòng lặp for với charAt() Nó duyệt chuỗi ngược từ chỉ mục cuối cùng đến vị trí 0. Nhà tuyển dụng thường yêu cầu phiên bản này vì nó thể hiện logic thay vì ủy thác cho bên thứ ba:

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

3. Hoán đổi hai con trỏ trong phương thức toCharArray() Chuyển đổi chuỗi thành mảng ký tự, sau đó hoán đổi các ký tự ngoài cùng vào trong cho đến khi các con trỏ gặp nhau ở giữa:

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

Kỹ thuật mảng tương tự đảo ngược một dãy số hoặc bất kỳ tập hợp có thứ tự nào khác, đó là lý do tại sao nó xuất hiện trong Java mảng Các bài tập cũng cần được thực hiện thường xuyên như đối với các loại nhạc cụ dây.

Độ phức tạp về thời gian và không gian của mỗi phương pháp

Bốn phiên bản này không có giá thành như nhau. Cả hai phương trình bậc hai bên dưới đều có chung một nguyên nhân: chúng tạo ra một chuỗi hoàn toàn mới ở mỗi bước, và việc sao chép n ký tự n lần là công việc n bình phương.

Phương pháp tiếp cậnThời gianKhông gian thêmTại sao
Đệ quy với chuỗi con()O (n²)O (n²)Hàm substring() sao chép các ký tự còn lại trong mỗi lần gọi và mỗi ký tự được giữ trong một khung ngăn xếp.
vòng lặp for với charAt() và +O (n²)O (n²)Mỗi phép nối chuỗi sẽ tạo ra một chuỗi mới và sao chép tất cả những gì đã được thu thập cho đến nay.
StringBuilder.reverse()O (n)O (n)Một bộ đệm có thể thay đổi, một lần xử lý và các cặp dữ liệu thay thế được giữ nguyên.
Hai con trỏ trỏ đến toCharArray()O (n)O (n)Một bản sao mảng, sau đó thực hiện n/2 thao tác hoán đổi mà không cần cấp phát thêm tài nguyên.

Hãy chọn phiên bản đệ quy để học hoặc để minh họa cách hoạt động của ngăn xếp cuộc gọi, phiên bản mảng ký tự khi người phỏng vấn yêu cầu viết logic thủ công, và StringBuilder.reverse() trong bất kỳ sản phẩm nào được cung cấp. Sự đánh đổi tương tự giữa giải pháp giảng dạy và giải pháp sản xuất xuất hiện trong các bài tập kinh điển, từ... phân loại bong bóngChuỗi Fibonacci đến kiểm tra số nguyên tốMỗi kỹ năng đều đáng để luyện tập. Java cả hai chiều.

Câu Hỏi Thường Gặp

Các đối tượng chuỗi (String) là bất biến, do đó các ký tự bên trong chúng không bao giờ thay đổi sau khi được tạo. Vì vậy, mỗi lần đảo ngược sẽ tạo ra một đối tượng mới. Hãy sử dụng StringBuilder hoặc mảng ký tự (char array) khi cần sửa đổi các ký tự mà không cần cấp phát một đối tượng String mới cho mỗi bước.

Lần gọi đầu tiên đến phương thức isEmpty() sẽ ném ra ngoại lệ NullPointerException, vì phương thức được gọi trên đối tượng rỗng. Hãy bảo vệ điểm vào bằng cách kiểm tra giá trị null, trả về null hoặc ném ra ngoại lệ IllegalArgumentException trước khi bất kỳ quá trình đệ quy nào bắt đầu.

Không đáng tin cậy. Phương thức charAt() hoạt động trên các đơn vị mã 16 bit, vì vậy một ký tự được lưu trữ dưới dạng cặp ký tự thay thế sẽ bị tách ra và văn bản đảo ngược sẽ hiển thị các ô vuông thay thế. Phương thức StringBuilder.reverse() giữ các cặp ký tự thay thế lại với nhau, điều này làm cho nó trở thành lựa chọn an toàn hơn cho văn bản Unicode.

Trong hầu hết các trường hợp, StringBuilder đều như vậy. Cả hai đều có cùng phương thức reverse(), nhưng String thì khác.Buffer Việc đồng bộ hóa mọi cuộc gọi sẽ làm giảm tốc độ. Hãy chọn String.Buffer chỉ khi một bộ đệm thực sự được chia sẻ giữa các luồng.

Tách câu dựa trên khoảng trắng bằng hàm split(" "), sau đó duyệt qua mảng kết quả từ chỉ mục cuối cùng đến chỉ mục đầu tiên, thêm từng từ vào một StringBuilder. Các ký tự bên trong mỗi từ vẫn giữ nguyên thứ tự ban đầu.

Mỗi ký tự sử dụng một khung ngăn xếp, vì vậy thông thường vài nghìn ký tự sẽ xuất hiện trước khi xảy ra lỗi StackOverflowError. Giới hạn chính xác phụ thuộc vào kích thước ngăn xếp của luồng JVM. Bất kỳ phiên bản lặp nào cũng hoàn toàn tránh được giới hạn trên.

Trợ lý AI có thể đọc một chồng tài liệu. tracVí dụ, chỉ ra trường hợp cơ sở bị thiếu hoặc không thể truy cập được, và giải thích thứ tự các khung được giải nén. Nó cũng soạn thảo các bài kiểm tra trường hợp ngoại lệ cho đầu vào trống, ký tự đơn và null. Kiểm chứng lập luận bằng một lần chạy thực tế.

Vâng. Phi công phụ Thông thường, toàn bộ phương thức đảo ngược được hoàn thiện chỉ từ chữ ký, thường đưa ra dạng StringBuilder trước. Hãy kiểm tra trường hợp cơ sở và độ phức tạp, vì gợi ý ngắn gọn nhất không phải lúc nào cũng là phiên bản mà bài tập yêu cầu.

Tóm tắt bài viết này với: