이 글에서는 자바(Java)에서 문자열을 여러 개의 부분 문자열(substring)로 분할하는 방법에 대해 알아보겠습니다. 먼저 기본 개념부터 살펴본 후, 실제 동작하는 코드 예제와 함께 단계별로 설명드리겠습니다.
부분 문자열이란?
문자열(String)은 하나 이상의 문자를 포함하며 큰따옴표(" ")로 묶인 데이터 타입입니다. 그리고 문자열의 일부 또는 부분 집합을 부분 문자열(substring)이라고 합니다.
예를 들어 아래와 같은 입력이 주어졌을 때 −
입력 문자열: JVM
원하는 출력 결과는 다음과 같습니다 −
ArrayList 형태로 출력된 부분 문자열 목록 : [J, JV, JVM, V, VM, M] 분할된 부분 문자열 : (1) "J" (2) "JV" (3) "JVM" (4) "V" (5) "VM" (6) "M"
길이가 3인 문자열 "JVM"에서 생성 가능한 모든 부분 문자열은 총 6개입니다. 시작 위치와 끝 위치를 조합하여 가능한 모든 경우의 수를 구하는 것이 핵심 원리입니다.
알고리즘
전체 로직은 다음과 같은 단계로 진행됩니다.
Step 1 - 시작 Step 2 - input_string이라는 이름의 문자열과 string_list라는 이름의 ArrayList를 선언한다. Step 3 - 값을 정의한다. Step 4 - 두 개의 중첩 반복문을 사용하여 문자열의 길이만큼 순회하며, 각 위치 조합에 해당하는 부분 문자열을 리스트에 추가한다. 이것이 콘솔에 출력될 결과이다. Step 5 - 부분 문자열 목록을 ArrayList 형태로 출력하기 위해 카운터를 초기화하고, 결과를 순회하면서 매 반복마다 카운터를 1씩 증가시킨다. 이를 통해 문자열에 포함된 부분 문자열의 총 개수를 알 수 있다. Step 6 - 결과를 화면에 출력한다. Step 7 - 종료
예제 1: main 함수 안에서 모든 연산 처리하기
첫 번째 예제에서는 모든 연산을 'main' 함수 하나에 묶어서 처리합니다.
import java.io.*;
import java.util.ArrayList;
public class SubString {
public static void main(String[] args) {
System.out.println("Required packages have been imported");
String input_string = "JVM";
System.out.println("The string is defined as: " +input_string);
int i, j;
int string_length = input_string.length();
ArrayList<String> string_list = new ArrayList<String>();
for (i = 0; i < string_length; i++) {
for (j = i + 1; j <= string_length; j++) {
string_list.add(input_string.substring(i, j));
}
}
ArrayList<String> result = string_list;
System.out.println( "\nThe substring list printed as an ArrayList : ");
System.out.println(result);
System.out.println( "\nThe sub-strings after splitting is: ");
int count = 1;
for (String it : result) {
System.out.println("(" + count + ") \"" + it + "\"");
count++;
}
}
}코드 설명
바깥쪽 반복문 변수 i는 부분 문자열의 시작 인덱스를, 안쪽 반복문 변수 j는 끝 인덱스를 담당합니다. 자바의 substring(i, j) 메서드는 시작 인덱스는 포함하고 끝 인덱스는 제외하므로, j를 i+1부터 문자열 길이까지 순회하면 해당 시작 위치에서 만들 수 있는 모든 부분 문자열이 생성됩니다.
출력 결과
Required packages have been imported The string is defined as: JVM The substring list printed as an ArrayList : [J, JV, JVM, V, VM, M] The sub-strings after splitting is: (1) "J" (2) "JV" (3) "JVM" (4) "V" (5) "VM" (6) "M"
예제 2: 객체 지향 방식으로 함수 분리하기
두 번째 예제에서는 연산 로직을 별도의 함수로 캡슐화하여 객체 지향 프로그래밍(OOP) 스타일로 작성합니다. 이렇게 하면 코드의 재사용성과 가독성이 향상됩니다.
import java.io.*;
import java.util.ArrayList;
public class SubString {
public static ArrayList<String> split_string(String input_string) {
int i, j;
int string_length = input_string.length();
ArrayList<String> string_list = new ArrayList<String>();
for (i = 0; i < string_length; i++) {
for (j = i + 1; j <= string_length; j++) {
string_list.add(input_string.substring(i, j));
}
}
return string_list;
}
public static void main(String[] args) {
System.out.println("Required packages have been imported");
String input_string = "JVM";
System.out.println("The string is defined as: " +input_string);
ArrayList<String> string_list = SubString.split_string(input_string);
System.out.println( "\nThe substring list printed as an ArrayList : ");
System.out.println(string_list);
System.out.println( "\nThe sub-strings after splitting is: ");
int count = 1;
for (String it : string_list) {
System.out.println("(" + count + ") \"" + it + "\"");
count++;
}
}
}코드 설명
부분 문자열을 생성하는 로직이 split_string()이라는 별도의 정적 메서드로 분리되었습니다. 이 메서드는 입력 문자열을 받아 부분 문자열 목록을 담은 ArrayList<String>을 반환하며, main 함수에서는 반환받은 리스트를 출력하기만 하면 됩니다.
출력 결과
Required packages have been imported The string is defined as: JVM The substring list printed as an ArrayList : [J, JV, JVM, V, VM, M] The sub-strings after splitting is: (1) "J" (2) "JV" (3) "JVM" (4) "V" (5) "VM" (6) "M"
마무리
지금까지 자바에서 문자열을 모든 부분 문자열로 분할하는 두 가지 방법을 살펴보았습니다. 첫 번째 방식은 간단한 스크립트나 학습용으로 적합하고, 두 번째 방식처럼 기능을 함수로 분리하면 유지보수와 재사용 측면에서 더 유리합니다. 참고로 길이가 n인 문자열의 부분 문자열 개수는 n(n+1)/2개이므로, 문자열이 길어질수록 생성되는 부분 문자열의 수가 빠르게 늘어난다는 점도 기억해 두시기 바랍니다.