Javaで文字列が回文かどうかを確認する

Shikha Chaudhary 2023年10月12日
  1. 文字列が Java の回文でポインタを使用してあるかどうかを確認する
  2. 文字列が Java の回文で文字列を逆にしてあるかどうかを確認する
  3. Java で文字列が回文であるかどうかを再帰的に確認する
  4. まとめ
Javaで文字列が回文かどうかを確認する

右から左への文字列の文字が左から右への文字列の文字と同じである場合、それを回文と呼びます。ababaradarppqpp などの文字列はいくつかの例です。

ここで、最初の文字は最後の文字と同じです。2 番目の文字は、最後から 2 番目の文字などと同じです。この記事では、さまざまな Java プログラムを調べて、文字列が回文であるかどうかを確認します。

文字列が Java の回文でポインタを使用してあるかどうかを確認する

文字列が回文であるかどうかを確認する非常に簡単な方法は、2つのポインタを使用することです。1つは文字列の先頭を指し、もう 1つは文字列の末尾を指します。次のコードを検討してください。

public class PalProgram {
  static boolean PalFunc(String s)

  {
    // Pointer i pointing to the start and j pointing to the end
    int i = 0, j = s.length() - 1;

    while (i < j) {
      // Check if there is any mis-matching pair
      if (s.charAt(i) != s.charAt(j))
        return false;

      // Update the pointers
      i++;
      j--;
    }

    // If no mismatch occurs
    return true;
  }

  public static void main(String[] args) {
    String s = "ava";
    s = s.toLowerCase();
    if (PalFunc(s))
      System.out.print("Yes, it is a palindrome.");

    else
      System.out.print("No, it is not a palindrome.");
  }
}

出力:

Yes, it is a palindrome.

ここで、PalFunc 関数内では、最初のポインターi が文字列の先頭を指し、2 番目のポインターj が文字列の末尾を指します。これは、回文であるかどうかを確認する必要があります。か否か。

次に、i<j までループを実行します。各ステップで、これら 2つのポインターij が指す文字が一致するかどうかを確認します。

また、i を同時にインクリメントし、j を 1つデクリメントします。どのステップでも文字が一致しない場合は、文字列が回文ではないことをユーザーに通知する false を返します。

この例では、toLowerCase() 関数を使用しています。Java コンパイラは、ASCII 値に基づいて 2つの文字を比較します。

これは、A == afalse を評価することを意味します。この場合、文字列 abA は Java の回文とは見なされません。これは、実際のシナリオではありません。

そのため、for ループで比較する前に、まず文字列を大文字または小文字に変換する必要があります。文字が大文字と小文字を混ぜる AVva のようなパリンドロームを扱うときに役立ちます。

文字列が Java の回文で文字列を逆にしてあるかどうかを確認する

文字列 aabcvbaa があるとします。まず、文字列を逆にします。結果の文字列は aabvcbaa になります。

元の文字列の最後の文字が、反転された文字列の最初の文字になります。元の文字列の最後から 2 番目の文字は、反転された文字列の 2 番目の文字になります。

これで、2つの文字列を文字ごとに比較して、文字列が回文であるかどうかを確認できます。不一致が発生した場合、文字列は回文ではなく、false を返すことができ、文字列が回文ではないことをユーザーに通知します。

ただし、全体で不一致が発生しない場合は、文字列が回文であると言って、true を返すことができます。この場合、同じ文字列で 2つのポインタを使用する代わりに、新しい逆文字列を作成しています(デモを参照)。

Java で提供されている組み込み関数を使用できない場合があります。したがって、Java API の reverse() メソッドは使用しません。

文字列を逆にする関数を記述します。

public class Solution {
  static boolean Sol(String s)

  {
    // reverse the string
    StringBuilder reversed_str = new StringBuilder();
    char[] newArray = s.toCharArray();
    for (int index = newArray.length - 1; index >= 0; index--) {
      reversed_str.append(newArray[index]);
    }

    // comparing the original string with the reversed string
    return (reversed_str.toString()).equals(s);
  }

  public static void main(String[] args) {
    String s = "raceCAR";

    // Convert the string to the lowercase
    s = s.toLowerCase();

    if (Sol(s))
      System.out.print("Yes, this string is a palindrome.");

    else
      System.out.print("No, it isn't a palindrome.");
  }
}

出力:

Yes, this string is a palindrome.

Sol 関数内で何が起こっているかを簡単に見てみましょう。最初に文字列を配列に変更し、次にこれを使用して文字列を逆にします。

次に、反転した文字列を元の文字列と文字ごとに比較します。

  1. StringBuilder クラス:Java の文字列クラスは、不変の文字列、つまり変更できない文字列を作成します。ここでは、文字を追加するために変更可能な文字列 reversed_str を作成します。Java の StringBuilder クラスは、可変文字列の作成に役立ちます。
  2. toCharArray メソッド:元の文字列と反転した文字列を文字ごとに比較するため、toCharArray() メソッドを使用して文字列を一連の文字に変換します。結果を配列 newArray に格納します。
  3. append() メソッド:元の文字列を文字配列に変更した後、それを使用して逆の文字列を作成します。このために、文字配列を最後からトラバースし、append() メソッドを使用して文字列 reversed_str に文字を追加し続けます。
  4. toString() メソッド:逆の文字列を作成した後、toString() メソッドを使用して再び文字列に変更します。これを行うのは、equals() メソッドを使用するだけで 2つの文字列を比較できるためです。
ノート
reversed_str に文字のシーケンスを追加しました。equals() メソッドは、文字シーケンスではなく文字列を比較します。
  1. equals() メソッド:最後に、元の文字列 s を反転した文字列 reversed_str と比較します。これを行うには、equals() メソッドを使用できます。このメソッドは、文字列のすべての文字が一致した場合に true を返します。

以下に示すように、Java API の reverse() メソッド(StringBuilder および StringBuffer)を使用すると、同じことを簡単に実現できます。

// Check if a string is a palindrome
// Java program

public class Solution {
  static boolean Sol(String s)

  { // Using the stringbuilder API
    StringBuilder newString = new StringBuilder(s);
    StringBuilder rev_str = newString.reverse();
    return (rev_str.toString()).equals(s);
  }

  public static void main(String[] args) {
    String s = "raceCAR";

    // Convert the string to the lowercase
    s = s.toLowerCase();

    if (Sol(s))
      System.out.print("Yes, it is a palindrome.");

    else
      System.out.print("No, it is not a palindrome.");
  }
}

出力:

Yes, it is a palindrome.

StringBuilder API を使用する場合、文字配列を作成したり、for ループを使用して文字列を逆にしたりする必要がないことに注意してください。この方法はクリーンでシンプルです。

StringBuilder クラスの詳細については、このドキュメントを参照してください。

以下に示すように、StringBuilderAPI を使用することもできます。

public class CheckPalindrome {
  static boolean Sol(String s)

  { // Using the stringbuffer API
    StringBuffer str = new StringBuffer(s);
    StringBuffer rev_str = str.reverse();
    return (rev_str.toString()).equals(s);
  }

  public static void main(String[] args) {
    String s = "raceCAR";

    // Convert the string to the lowercase
    s = s.toLowerCase();

    if (Sol(s))
      System.out.print("Yes, it is a palindrome.");

    else
      System.out.print("No, it is not a palindrome.");
  }
}

出力:

Yes, it is a palindrome.

コードが同じように見えるため、StringBuilder クラスと StringBuffer クラスが何が違うのか不思議に思うかもしれません。

StringBuffer クラスでは、一度に 1つのスレッドのみがこのメソッドを呼び出すことができます。同期されます。

一方、StringBuilder メソッドは、複数のスレッドから同時に呼び出すことができます。同期されていません。

ただし、StringBuilder クラスは StringBuffer クラスよりも効率的です。StringBuffer クラスの詳細については、このドキュメントを参照してください。

Java で文字列が回文であるかどうかを再帰的に確認する

Sol 関数を再帰的に呼び出して、文字列が回文であるかどうかを確認できます。基本的な考え方は、文字列を反復処理するために再帰を使用することです。

public class Solution {
  static boolean Sol(String s)

  {
    s = s.toLowerCase();
    return RecursePal(s, 0, s.length() - 1);
  }

  static boolean RecursePal(String s, int f, int b) {
    if (f == b) {
      return true;
    }
    if ((s.charAt(f)) != (s.charAt(b))) {
      return false;
    }
    if (f < b + 1) {
      return RecursePal(s, f + 1, b - 1);
    }
    return true;
  }

  public static void main(String[] args) {
    String s = "raceCAR";

    // Convert the string to the lowercase
    s = s.toLowerCase();

    if (Sol(s))
      System.out.print("Yes");

    else
      System.out.print("No");
  }
}

出力:

Yes

ここでは、関数 RecursePal を定義します。文字列 s、最初の文字のインデックスを f、最後の文字のインデックスを b として引数として渡します。

次に、f の文字が b の文字と同じであるかどうかを確認します。はいの場合、true を返します。

それ以外の場合は、false を返します。最後に、もう一度 RecursePal 関数を呼び出して、文字列全体に対してこのプロセスを繰り返します。

この関数を再帰的に呼び出すたびに、f インデックスをインクリメントし、b インデックスを 1つデクリメントします。

まとめ

このチュートリアルでは、文字列が回文であるかどうかを確認するための Java のさまざまな方法を見ました。

2 ポインターを使用して、文字列を双方向でループする方法を学びました。また、文字列を逆にして Java で再帰を使用することにより、文字列が回文であるかどうかを確認する方法も確認しました。

関連記事 - Java String