1. StringBuilder/StringBuffer
Cách phổ biến và đơn giản nhất là sử dụng StringBuilder/StringBuffer :public static String reverseString(String str) {
return new StringBuilder(str).reverse().toString();
}
Giải pháp tốt nhất = đơn giản nhất. Khi được hỏi cách đảo ngược một chuỗi trong Java, đây là điều đầu tiên bạn nên nghĩ đến. Nhưng chúng ta đã nói về thuật toán trước đó phải không? Chúng ta hãy xem xét các giải pháp vượt trội.
2. Giải pháp mảng
public static String reverseString(String str) {
char[] array = str.toCharArray();
String result = "";
for (int i = array.length - 1; i >= 0; i--) {
result = result + array[i];
}
return result;
}
Chúng tôi chuyển đổi chuỗi của mình thành một mảng bằng phương thức toCharArray . Hãy chạy vòng lặp for qua mảng này từ cuối mảng, thêm các ký tự vào chuỗi kết quả trong suốt quá trình.
3. Giải pháp với charAt
public static String reverseString(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
result = str.charAt(i) + result;
}
return result;
}
Trong trường hợp này, chúng ta thậm chí không phải chia chuỗi thành một mảng, vì chúng ta trích xuất từng ký tự bằng phương thức lớp String - charAt (vòng lặp for, một lần nữa, ngược lại, cho phép chúng ta lấy các ký tự theo tuần tự ngược).
4. Giải pháp với ngăn xếp
Lớp Stack đã không được sử dụng trong một thời gian dài và được coi là lỗi thời, tuy nhiên, để tham khảo, sẽ rất hữu ích khi xem xét giải pháp sử dụng nó:public static String reverseString(String str) {
Stack<Character> stack = new Stack<>();
String result = "";
for (Character character : str.toCharArray()) {
stack.add(character);
}
while (!stack.isEmpty()) {
result = result + stack.pop();
}
return result;
}
Ở đây một lần nữa chúng ta sử dụng toCharArray để chia chuỗi thành một mảng và đặt tất cả vào Stack của chúng ta với kiểu chung là Character . Tiếp theo, chúng ta bắt đầu lấy các phần tử từ đầu ngăn xếp. Do tính chất của ngăn xếp là cấu trúc LIFO - L ast I n F irst O ut (vào trước, ra sau) nên các phần tử sẽ được đưa ngược lại và kết quả sẽ được lưu ở hàng kết quả.
5. Giải bằng đệ quy
Hầu hết mọi vấn đề thuật toán đều có thể được giải quyết bằng đệ quy. Và ở đây chúng tôi cũng không thể làm gì nếu không có cô ấy. Hoặc thậm chí không có chúng. Rốt cuộc, hôm nay chúng ta sẽ xem xét không chỉ một phương pháp giải đệ quy mà còn nhiều phương pháp khác.-
phương pháp một
public static String reverseString(String str) { String rightStr; String leftStr; int length = str.length(); if (length <= 1) { return str; } leftStr = str.substring(0, length / 2); rightStr = str.substring(length / 2, length); return reverseString(rightStr) + reverseString(leftStr); }
Chúng ta sử dụng các biến rightStr và leftStr để chia chuỗi đến thành hai phần bằng nhau. Tiếp theo, sử dụng cách phân tách này, chúng ta chia chuỗi thành những phần chia nhỏ nhất (1 ký tự). Sau đó, đệ quy bắt đầu sụp đổ, trả về các ký tự theo thứ tự ngược lại (những ký tự bên phải được đặt ở bên trái; những ký tự ở bên trái được đặt ở bên phải)
Chúng ta không được quên rằng mỗi lần đệ quy là một lệnh gọi nhiều phương thức và kết quả là tiêu tốn đáng kể nguồn lực. Chà, nếu chúng ta đang nói về đệ quy với điều kiện thoát không thể đạt được, thì đây là con đường dẫn đến vô cực và StackOverflowError.
-
phương pháp hai
Ở đây chúng ta cần một đối số bổ sung trong phương thức - index.
Khi phương thức này được chạy, nó có độ dài chuỗi là -1:
String str = "JavaRush forever"; System.out.println(reverseString(str, str.length()-1));
Và chính phương pháp này:
public static String reverseString(String str, int index) { if(index == 0){ return str.charAt(0) + ""; } char letter = str.charAt(index); return letter + reverseString(str, index-1); }
Chỉ mục của chúng tôi đóng vai trò là chỉ báo về phần tử hàng nào chúng tôi sẽ sử dụng bây giờ (và chúng tôi sẽ sử dụng các phần tử từ cuối).
Do đó, chúng ta đặt điều kiện thoát khi chỉ mục đạt đến phần tử đầu tiên.
- phương pháp ba
public static String reverseString(String str) { if (str.length() <= 1) { return str; } return reverseString(str.substring(1)) + str.charAt(0); }
Phương pháp này về cơ bản là đơn giản nhất trong số các phương pháp đệ quy. Và như chúng ta nhớ, đơn giản = tốt nhất.
Trong mỗi lần chạy, chúng tôi chỉ định cùng một chuỗi nhưng không có phần tử đầu tiên. Khi đạt đến điều kiện thoát (khi chúng ta còn một ký tự), đệ quy bắt đầu thu gọn và ký tự không được sử dụng trước đó sẽ được thêm vào mỗi kết quả tiếp theo.
Chúng tôi thêm các giá trị thu được bằng cách sử dụng chỉ mục chữ cái với kết quả thực hiện phương thức trước đó và trả về kết quả.
6. Sử dụng XOR
XOR là một phép toán logic theo bit. Trong trường hợp có hai biến, kết quả của một phép toán là đúng khi và chỉ khi một trong các đối số là đúng và đối số kia là sai.MỘT | B | Y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
(A XOR B) XOR B = A
(A XOR B) XOR A = B
Phương thức này sẽ trông như thế nào:
public static String reverseString(String str) {
char[] arr = str.toCharArray();
int low = 0;
int high = arr.length - 1;
String result = "";
while (low < high) {
arr[low] = (char) (arr[low] ^ arr[high]);
arr[high] = (char) (arr[low] ^ arr[high]);
arr[low] = (char) (arr[low] ^ arr[high]);
low++;
high--;
}
for (int i = 0; i < arr.length; i++) {
result = result + arr[i];
}
return result;
}
Chúng ta hãy tìm hiểu những gì đang xảy ra ở đây. Chúng tôi tạo một mảng từ chuỗi đến. Chúng ta tạo hai biến low và high để lưu trữ các chỉ mục để duyệt mảng. Theo đó, một cái sẽ di chuyển từ đầu đến cuối - chúng tôi đặt cho nó giá trị 0, thứ hai - từ đầu đến đầu, chúng tôi đặt nó arr.length - 1 . Chúng ta vào một vòng lặp sẽ phát miễn là chỉ số cao lớn hơn chỉ số thấp . Đây là nơi những điều thú vị bắt đầu xảy ra - việc sử dụng OR độc quyền. Hãy xem x và y làm ví dụ . Giả sử arr[high] = 'x'; Mã nhị phân của nó sẽ là 1 1 1 1 0 0 0 Lúc này arr[high] = 'n'; Mã nhị phân - 1 1 0 1 1 1 0 Những gì chúng ta sẽ có trong các phép toán XOR trong một vòng lặp:
-
mảng[thấp] = (char) (arr[thấp] ^ mảng[cao]);
arr[low] = 1 1 0 1 1 1 0 arr[high] =1 1 1 1 0 0 0 arr[low] = 0 0 1 0 1 1 0
-
mảng[cao] = (char) (arr[thấp] ^ mảng[cao]);
arr[low] = 0 0 1 0 1 1 0 arr[high] = 1 1 1 1 0 0 0 arr[high] = 1 1 0 1 1 1 0
-
mảng[thấp] = (char) (arr[thấp] ^ mảng[cao]);
arr[low] = 0 0 1 0 1 1 0 arr[high] = 1 1 0 1 1 1 0 arr[low] = 1 1 1 1 0 0 0
GO TO FULL VERSION