판그램(Pangram)이란?
이 글에서는 자바(Java)를 활용해 주어진 문자열이 판그램(Pangram)인지 확인하는 방법을 단계별로 알아봅니다. 판그램이란 대소문자 구분 없이 영어 알파벳의 모든 문자(a~z)를 최소 한 번씩 포함하고 있는 문자열을 의미합니다. "The quick brown fox jumps over the lazy dog"처럼 알파벳 전체를 담고 있는 문장이 대표적인 예입니다.
아래는 본문에서 사용할 실행 예시입니다.
입력 값:
Input string: Abcdefghijklmnopqrstuvwxyz
기대 출력 결과:
Yes, the string is a pangram
알고리즘
Step 1 - START Step 2 - input_string이라는 이름의 문자열 변수를 선언한다. Step 3 - 문자열 값을 정의한다. Step 4 - 입력 문자열을 소문자로 변환한다. Step 5 - 문자열의 각 문자를 순회하며 charAt(i) - 'a' 연산으로 각 알파벳의 등장 여부를 boolean 배열에 기록한다. 26개 알파벳이 모두 등장했다면 해당 문자열은 판그램이다. Step 6 - 결과를 출력한다. Step 7 - STOP
예제 1: main 함수 안에서 모든 로직 처리하기
첫 번째 예제는 모든 연산을 'main' 함수 안에서 함께 수행하는 절차적 방식입니다.
public class Pangram {
static int size = 26;
static boolean isLetter(char ch) {
if (!Character.isLetter(ch))
return false;
return true;
}
public static void main(String args[]) {
String input_string = "Abcdefghijklmnopqrstuvwxyz";
System.out.println("The string is defined as: " + input_string);
int string_length = input_string.length();
input_string = input_string.toLowerCase();
boolean[] is_true = new boolean[size];
for (int i = 0; i < string_length; i++) {
if (isLetter(input_string.charAt(i))) {
int letter = input_string.charAt(i) - 'a';
is_true[letter] = true;
}
}
boolean result = true;
for (int i = 0; i < size; i++) {
if (!is_true[i]) {
result = false;
break;
}
}
if (result)
System.out.println("\nYes, the string is a pangram");
else
System.out.println("\nNo, the string is not a pangram");
}
}
출력 결과
The string is defined as: Abcdefghijklmnopqrstuvwxyz Yes, the string is a pangram
동작 원리: 먼저 toLowerCase()로 입력 문자열을 소문자로 변환한 뒤, 길이가 26인 boolean 배열(is_true)을 생성합니다. 각 문자에서 'a'를 빼면 0~25 사이의 인덱스가 계산되며, 해당 위치를 true로 표시합니다. 마지막으로 배열을 확인하여 false가 하나라도 남아 있으면 판그램이 아닌 것으로 판정합니다.
예제 2: 객체 지향 방식으로 메서드 분리하기
두 번째 예제는 핵심 로직을 별도의 메서드로 캡슐화하여 객체 지향 프로그래밍(OOP) 스타일로 작성한 코드입니다.
public class Pangram {
static int size = 26;
static boolean isLetter(char ch) {
if (!Character.isLetter(ch))
return false;
return true;
}
static boolean check_alphabets(String input_string, int string_length) {
input_string = input_string.toLowerCase();
boolean[] is_true = new boolean[size];
for (int i = 0; i < string_length; i++) {
if (isLetter(input_string.charAt(i))) {
int letter = input_string.charAt(i) - 'a';
is_true[letter] = true;
}
}
for (int i = 0; i < size; i++) {
if (!is_true[i])
return false;
}
return true;
}
public static void main(String args[]) {
String input_string = "Abcdefghijklmnopqrstuvwxyz";
System.out.println("The string is defined as: " + input_string);
int string_length = input_string.length();
if (check_alphabets(input_string, string_length))
System.out.println("\nYes, the string is a pangram");
else
System.out.println("\nNo, the string is not a pangram");
}
}
출력 결과
The string is defined as: Abcdefghijklmnopqrstuvwxyz Yes, the string is a pangram
isLetter() 메서드는 문자가 실제 알파벳인지 검사하고, check_alphabets() 메서드는 알파벳 포함 여부를 판정합니다. 이처럼 역할별로 메서드를 분리하면 코드의 가독성과 재사용성이 크게 향상됩니다.
마무리
두 예제 모두 시간 복잡도는 O(n)(n은 문자열 길이), 공간 복잡도는 O(1)로, 크기가 고정된 26칸짜리 배열만 사용하므로 매우 효율적입니다. 또한 Character.isLetter() 검사를 통해 공백, 숫자, 특수문자를 걸러내므로 실제 문장이 입력되더라도 안정적으로 판그램 여부를 확인할 수 있습니다.