Java에서 문자열이 회문인지 확인
오른쪽에서 왼쪽으로 문자열의 문자가 왼쪽에서 오른쪽으로 문자열의 문자와 같으면 이를 회문(palindrome)
이라고 합니다. ababa
, radar
및 ppqpp
와 같은 문자열이 몇 가지 예입니다.
여기서 첫 번째 문자는 마지막 문자와 동일합니다. 두 번째 문자는 마지막 두 번째 문자와 동일합니다. 이 기사에서는 문자열이 회문인지 여부를 확인하기 위해 다양한 Java 프로그램을 살펴보겠습니다.
포인터를 사용하여 Java에서 문자열이 회문인지 확인
문자열이 회문인지 여부를 확인하는 매우 간단한 아이디어는 두 개의 포인터를 사용하는 것입니다. 하나는 문자열의 시작을 가리키고 다른 하나는 문자열의 끝을 가리킵니다. 다음 코드를 고려하십시오.
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
는 문자열의 시작을 가리키고 두 번째 포인터 j
는 문자열의 끝을 가리키며 이것이 회문인지 확인해야 합니다. 아니면.
그런 다음 i<j
까지 루프를 실행합니다. 각 단계에서 i
와 j
라는 두 포인터가 가리키는 문자가 일치하는지 여부를 확인합니다.
또한 i
를 동시에 증가시키고 j
를 1만큼 감소시킵니다. 문자가 어떤 단계에서도 일치하지 않으면 문자열이 회문(palindrome)이 아님을 사용자에게 알리는 false
를 반환합니다.
이 예에서는 toLowerCase()
함수를 사용하고 있습니다. Java 컴파일러는 ASCII
값을 기준으로 두 문자를 비교합니다.
이는 A ==
가 false
로 평가됨을 의미합니다. 이 경우 문자열 abA
는 실제 시나리오가 아닌 Java에서 회문으로 간주되지 않습니다.
이것이 for
루프에서 비교하기 전에 먼저 문자열을 대문자 또는 소문자로 변환해야 하는 이유입니다. 문자가 대문자와 소문자를 혼합하는 AVva
와 같은 회문을 처리할 때 유용합니다.
Java에서 문자열이 회문인지 확인하기 위해 문자열을 뒤집습니다
aabcvbaa
문자열이 있다고 가정합니다. 먼저 문자열을 반대로 해보자. 결과 문자열은 aabvcbaa
가 됩니다.
원래 문자열의 마지막 문자는 반전된 문자열의 첫 번째 문자가 됩니다. 원래 문자열의 마지막 두 번째 문자는 반전된 문자열의 두 번째 문자가 되는 식입니다.
이제 두 문자열을 문자별로 비교하여 해당 문자열이 회문인지 확인할 수 있습니다. 불일치가 발생하면 문자열은 회문이 아니며 false
를 반환하여 사용자에게 문자열이 회문이 아님을 알릴 수 있습니다.
그러나 전체에서 불일치가 발생하지 않으면 문자열이 회문이라고 말하면서 true
를 반환할 수 있습니다. 이 경우 동일한 문자열에 두 개의 포인터를 사용하는 대신 새로운 반전된 문자열을 만듭니다(데모 참조).
때로는 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()
메소드를 사용하여 두 문자열을 비교할 수 있기 때문에 이 작업을 수행합니다.
reversed_str
에 문자 시퀀스를 추가했으며 equals()
메서드는 문자 시퀀스가 아닌 문자열을 비교합니다.equals()
메소드: 마지막으로 원래 문자열s
를 역 문자열reversed_str
과 비교합니다. 이렇게 하려면 문자열의 모든 문자가 일치하는 경우true
를 반환하는equals()
메서드를 사용할 수 있습니다.
아래와 같이 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
클래스는 한 번에 하나의 스레드만 이 메서드를 호출할 수 있도록 합니다. 동기화됩니다.
반면 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에서 문자열을 반전하고 재귀를 사용하여 문자열이 회문인지 확인하는 방법도 보았습니다.