1. 文字列ビルダー/文字列バッファ
最も一般的で簡単な方法は、StringBuilder/StringBufferを使用することです。public static String reverseString(String str) {
return new StringBuilder(str).reverse().toString();
}
最良の解決策 = 最もシンプルです。Java で文字列を反転する方法を尋ねられたとき、これが最初に思い浮かぶはずです。でも、アルゴリズムについては先ほど話しましたね。すぐに使えるソリューションではないソリューションを見てみましょう。
2. アレイソリューション
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;
}
toCharArrayメソッド を使用して文字列を配列に変換します。この配列の最後からforループを実行し、途中で結果の文字列に文字を追加してみましょ う。
3. charAt を使用した解決策
public static String reverseString(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
result = str.charAt(i) + result;
}
return result;
}
この場合、 StringクラスメソッドcharAt を 使用して各文字を抽出するため、文字列を配列に分割する必要さえありません(for ループも逆であり、文字を順番に逆方向に取得できます)。
4. スタックによるソリューション
Stackクラスは長い間使用されておらず、廃止されたものと考えられていますが、それでも、参考のために、それを使用したソリューションを検討することは役に立ちます。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;
}
ここでもtoCharArrayを使用して文字列を配列に分割し、それをすべてジェネリック型Characterを使用してスタックに置きます。次に、スタックの最上位から要素を取得し始めます。LIFO構造としてのスタックの性質 (後入れ先出し) により、要素は逆方向に取得され、結果は結果の行に格納され ます。
5. 再帰による解決
ほとんどすべてのアルゴリズムの問題は再帰を使用して解決できます。そしてここでも私たちは彼女なしではやっていけません。あるいはそれらがなくても。結局のところ、今日は再帰を解決する 1 つの方法だけではなく、いくつかの方法を検討します。-
方法 1
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); }
rightStr変数とleftStr変数を使用して、受信文字列を 2 つの等しい部分に分割します。次に、この分割を使用して、文字列を分割可能な最小の部分 (1 文字) に分割します。その後、再帰は崩壊し始め、逆の順序で文字が返されます (右側にあった文字は左側に配置され、左側にあった文字は右側に配置されます)。
各再帰はメソッドへの複数回の呼び出しであり、その結果、かなりのリソースが消費されることを忘れてはなりません。そうですね、達成不可能な終了条件を伴う再帰について話している場合、これは無限大と StackOverflowError へのパスです。
-
方法 2
ここでは、メソッドに追加の引数、index が必要です。
このメソッドを実行すると、文字列の長さは -1 に設定されます。
String str = "JavaRush forever"; System.out.println(reverseString(str, str.length()-1));
そしてメソッド自体は次のようになります。
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); }
インデックスは、現在どの行要素を使用するかを示すインジケーターとして機能します (最後からの要素を使用します)。
したがって、インデックスが最初の要素に到達したときに終了条件を設定します。
- 方法 3
public static String reverseString(String str) { if (str.length() <= 1) { return str; } return reverseString(str.substring(1)) + str.charAt(0); }
このメソッドは本質的に、再帰的なメソッドの中で最も単純です。そして、私たちが覚えているように、シンプル = 最高です。
各実行中に、同じ文字列を指定しますが、最初の要素は指定しません。終了条件に達すると (文字が 1 文字残ったとき)、再帰は崩壊し始め、以前の未使用の文字が後続の各結果に追加されます。
文字インデックスを使用して取得した値を、メソッドの前回の実行結果と加算し、結果を返します。
6. XOR の使用
XORはビット単位の論理演算です。2 つの変数の場合、演算の結果は、引数の一方が true で、もう一方が false の場合にのみ true になります。あ | 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
メソッドは次のようになります。
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;
}
ここで何が起こっているのか見てみましょう。受信文字列から配列を作成します。配列を走査するためのインデックスを格納する2 つの変数lowとhighを作成します。したがって、1 つは最初から最後に移動します - 値 0 を与え、2 つ目は - 終わりから始まりに移動し、arr.length - 1に設定します。インデックスhigh がlowより大きい限り再生されるループに入ります。ここで、排他的 OR の使用という楽しいことが始まります。例としてxとyを見てみましょう。arr[high] = 'x'; と仮定します。 そのバイナリ コードは 1 1 1 1 0 0 0 になります。この時点では、arr[high] = 'n'; となります。 バイナリ コード - 1 1 0 1 1 1 0 ループ内の XOR 演算では次のようになります。
-
arr[low] = (char) (arr[low] ^ arr[high]);
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
-
arr[高] = (文字) (arr[低] ^ arr[高]);
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
-
arr[low] = (char) (arr[low] ^ arr[high]);
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