JavaRush /Java Blog /Random-JA /Java で文字列を反転する: さまざまな方法で文字列を反転する方法を学習します

Java で文字列を反転する: さまざまな方法で文字列を反転する方法を学習します

Random-JA グループに公開済み
アルゴリズムを知らなくても優れたプログラマーになることは可能ですか? 非常に物議を醸しています。はい、当社のアウトソーシング会社で仕事を見つけることができます。面接では主にテクノロジーに関する質問をされるからです。 Java で文字列を反転する: さまざまな方法で文字列を反転する方法を学ぶ - 1しかし、松葉杖をつきながら決断を下したとしても、あなたは優れたスペシャリストになれるでしょうか? より本格的な外資系企業に転職したい場合は、主にアルゴリズムに焦点を当てた面接に遭遇することになります。いずれにせよ、アルゴリズムはプログラマーの友人であるため、最も基本的なアルゴリズムを採用する価値があります。今日はこれらのトピックの 1 つに触れ、文字列を反転する方法について説明します。ここではすべてがシンプルです。文字列を反転すると、文字列が逆になります。例: JavaRush 永久 ->reverof hsuRavaJ それでは、Java で文字列を反転するにはどうすればよいでしょうか?

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 つの変数lowhighを作成します。したがって、1 つは最初から最後に移動します - 値 0 を与え、2 つ目は - 終わりから始まりに移動し、arr.length - 1に設定します。インデックスhigh がlowより大きい限り再生されるループに入ります。ここで、排他的 OR の使用という楽しいことが始まります。例としてxyを見てみましょう。arr[high] = 'x'; と仮定します。 そのバイナリ コードは 1 1 1 1 0 0 0 になります。この時点では、arr[high] = 'n'; となります。 バイナリ コード - 1 1 0 1 1 1 0 ループ内の XOR 演算では次のようになります。
  1. 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
  2. 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
  3. 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
結果として、これらの操作のおかげで、2 つの配列セルの値が交換されました。 arr[high] は、arr[low] の先頭からの要素と同じ数の、配列の末尾からの要素です。したがって、要素をこれらのインデックスと単純に交換します。たとえば、「JavaRush 永遠に」という文の最初の実行では Jrが交換され、2 回目の実行ではaeなどが交換されます。文字数が奇数の場合は、中央の要素では、ループから除外されます (つまり、中央の要素を変更する必要はありません)。偶数の場合は、すべての要素を処理した後に廃棄されます。その後、通常のループに入り、配列要素から文字列を構築します。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION