Javaで文字列が回文かどうかを確認する
- 文字列が Java の回文でポインタを使用してあるかどうかを確認する
- 文字列が Java の回文で文字列を逆にしてあるかどうかを確認する
- Java で文字列が回文であるかどうかを再帰的に確認する
- まとめ
右から左への文字列の文字が左から右への文字列の文字と同じである場合、それを回文
と呼びます。ababa
、radar
、ppqpp
などの文字列はいくつかの例です。
ここで、最初の文字は最後の文字と同じです。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つのポインターi
と j
が指す文字が一致するかどうかを確認します。
また、i
を同時にインクリメントし、j
を 1つデクリメントします。どのステップでも文字が一致しない場合は、文字列が回文ではないことをユーザーに通知する false
を返します。
この例では、toLowerCase()
関数を使用しています。Java コンパイラは、ASCII
値に基づいて 2つの文字を比較します。
これは、A == a
が false
を評価することを意味します。この場合、文字列 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
関数内で何が起こっているかを簡単に見てみましょう。最初に文字列を配列に変更し、次にこれを使用して文字列を逆にします。
次に、反転した文字列を元の文字列と文字ごとに比較します。
StringBuilder
クラス:Java の文字列クラスは、不変の文字列、つまり変更できない文字列を作成します。ここでは、文字を追加するために変更可能な文字列reversed_str
を作成します。Java のStringBuilder
クラスは、可変文字列の作成に役立ちます。toCharArray
メソッド:元の文字列と反転した文字列を文字ごとに比較するため、toCharArray()
メソッドを使用して文字列を一連の文字に変換します。結果を配列newArray
に格納します。append()
メソッド:元の文字列を文字配列に変更した後、それを使用して逆の文字列を作成します。このために、文字配列を最後からトラバースし、append()
メソッドを使用して文字列reversed_str
に文字を追加し続けます。toString()
メソッド:逆の文字列を作成した後、toString()
メソッドを使用して再び文字列に変更します。これを行うのは、equals()
メソッドを使用するだけで 2つの文字列を比較できるためです。
reversed_str
に文字のシーケンスを追加しました。equals()
メソッドは、文字シーケンスではなく文字列を比較します。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
クラスの詳細については、このドキュメントを参照してください。
以下に示すように、StringBuilder
API を使用することもできます。
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 で再帰を使用することにより、文字列が回文であるかどうかを確認する方法も確認しました。