Post

Java 문자열 Palindrome 확인

1. Palindrome

Palindrome은 단어, 구, 숫자 또는 “madam” 또는 “racecar”와 같이 앞뒤로 똑같이 읽는 일련의 문자이다.

2. Palindrome 확인 방법

1) 간단한 접근

주어진 문자열을 한 번에 한 문자씩 앞뒤로 동시에 반복할 수 있다. 일치하는 항목이 있으면 루프가 계속된다. 그렇지 않으면 루프가 종료된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public boolean isPalindrome(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    int length = clean.length();
    int forward = 0;
    int backward = length - 1;
    while (backward > forward) {
        char forwardChar = clean.charAt(forward++);
        char backwardChar = clean.charAt(backward--);
        if (forwardChar != backwardChar)
            return false;
    }
    return true;
}

2) 문자열 반전

Palindrome을 확인할 때 StringBuilder 및 StringBuffer 클래스의 API 메소드를 사용하거나 이러한 클래스 없이 String을 되돌릴 수 있다.

먼저 helper API가 없는 코드 구현이다.

1
2
3
4
5
6
7
8
9
public boolean isPalindromeReverseTheString(String text) {
    StringBuilder reverse = new StringBuilder();
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    char[] plain = clean.toCharArray();
    for (int i = plain.length - 1; i >= 0; i--) {
        reverse.append(plain[i]);
    }
    return (reverse.toString()).equals(clean);
}

위의 스니펫에서 단순히 마지막 문자에서 주어진 문자열을 반복하고 각 문자를 다음 문자에 추가한다.

마지막으로 주어진 문자열과 반전된 문자열 사이의 동등성을 테스트한다.

API 메서드를 사용하여 동일한 동작을 달성할 수 있다.

간단한 데모이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public boolean isPalindromeUsingStringBuilder(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    StringBuilder plain = new StringBuilder(clean);
    StringBuilder reverse = plain.reverse();
    return (reverse.toString()).equals(clean);
}

public boolean isPalindromeUsingStringBuffer(String text) {
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    StringBuffer plain = new StringBuffer(clean);
    StringBuffer reverse = plain.reverse();
    return (reverse.toString()).equals(clean);
}

코드 스니펫에서 StringBuilder 및 StringBuffer API의 reverse() 메서드를 호출 하여 주어진 문자열을 역전시키고 동일성을 테스트한다.

3) 스트림 API 사용

IntStream을 사용하여 솔루션을 제공할 수 있다.

1
2
3
4
5
public boolean isPalindromeUsingIntStream(String text) {
    String temp  = text.replaceAll("\\s+", "").toLowerCase();
    return IntStream.range(0, temp.length() / 2)
      .noneMatch(i -> temp.charAt(i) != temp.charAt(temp.length() - i - 1));
}

위의 스니펫에서 문자열의 각 끝에서 나온 문자 쌍 중 어느 것도 술어 조건을 충족하지 않는지 확인한다.

4) 재귀 사용

재귀는 이러한 종류의 문제를 해결하는 매우 인기 있는 방법이다. 예제에서 주어진 String을 재귀적으로 반복하고 그것이 회문인지 아닌지를 알아보기 위해 테스트한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public boolean isPalindromeRecursive(String text){
    String clean = text.replaceAll("\\s+", "").toLowerCase();
    return recursivePalindrome(clean,0,clean.length()-1);
}

private boolean recursivePalindrome(String text, int forward, int backward) {
    if (forward == backward) {
        return true;
    }
    if ((text.charAt(forward)) != (text.charAt(backward))) {
        return false;
    }
    if (forward < backward + 1) {
        return recursivePalindrome(text, forward + 1, backward - 1);
    }

    return true;
}

[출처 및 참고]

This post is licensed under CC BY 4.0 by the author.