일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 플러터 개발환경 설정
- php 프로그래밍
- php 프로그래밍 입문 연습문제
- 플러터
- 백준
- 자바
- php
- SWEA
- php 프로그래밍 입문 문제풀이
- JAVA SPRING
- php 프로그래밍 입문
- 파이썬
- 페이코 친구코드
- 한정 분기
- spring
- 최단 경로
- C
- php 프로그래밍 입문 예제
- Flutter
- 자바 스프링
- 페이코 초대코드
- 페이코 추천인
- Java
- 스프링
- C언어
- programmers
- 배열
- 페이코 추천인코드
- php 프로그래밍 입문 3판
- php 프로그래밍 입문 솔루션
Archives
- Today
- Total
11-07 11:40
ImJay
[BOJ/Java] 1786. 찾기 본문
반응형
[BOJ/Java] 1786. 찾기
문제 해석
문자열에서 특정 패턴을 찾는 문제로, 주어진 텍스트 문자열(T)에서 패턴 문자열(P)이 등장하는 모든 위치를 찾아 그 시작 위치들을 출력하는 것이다. 이 문제는 문자열 검색 알고리즘 중 하나인 KMP(Knuth-Morris-Pratt) 알고리즘을 사용하여 해결할 수 있다. KMP 알고리즘은 불필요한 문자 비교를 최소화하여 빠른 검색을 가능하게 한다.
풀이 과정
- 입력 받기: 문자열 T와 패턴 P를 입력 받는다.
- KMP 실행: KMP 알고리즘의 메인 로직을 실행한다.
- 실패 함수 생성: 패턴 P에 대한 실패 함수를 생성한다. 이 함수는 패턴 내에서 불일치가 발생했을 때, 어느 위치로 점프할지 결정한다.
- 검색 함수: 실패 함수를 사용하여 전체 텍스트 T에서 패턴 P를 검색한다.
- 결과 출력: 검색 결과로 나온 패턴의 위치와 개수를 출력한다.
코드
import java.io.*;
public class Main {
private static char[] T, P; // 텍스트와 패턴을 저장할 배열
private static int[] F; // 실패 함수를 저장할 배열
private static StringBuilder ans = new StringBuilder(); // 결과 위치를 저장할 StringBuilder
private static int cnt = 0; // 패턴이 나타난 횟수
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
T = br.readLine().toCharArray(); // 텍스트 T를 입력받음
P = br.readLine().toCharArray(); // 패턴 P를 입력받음
KMP(); // KMP 알고리즘 실행
sb.append(cnt).append("\n"); // 패턴이 나타난 횟수 출력
sb.append(ans.toString()); // 모든 위치 출력
bw.write(sb.toString());
bw.flush();
bw.close();
}
private static void KMP() {
getFailureFunction(); // 실패 함수를 생성
search(); // 텍스트에서 패턴 검색
}
private static void getFailureFunction() {
F = new int[P.length];
int i = 1, j = 0;
while (i < P.length) {
if (P[i] == P[j]) F[i++] = ++j; // 패턴 내에서 일치하는 경우
else if (j > 0) j = F[j - 1]; // 불일치시 이전 일치 지점으로 점프
else i++; // 일치하는 부분이 전혀 없는 경우
}
}
private static void search() {
int i = 0, j = 0;
while (i < T.length) {
if (T[i] != P[j]) {
if (j > 0) j = F[j - 1]; // 불일치시 실패 함수에 따라 점프
else i++;
} else {
if (j == P.length - 1) { // 패턴이 완전히 일치하는 경우
ans.append(i - j + 1).append(" "); // 위치 저장
cnt++; // 카운트 증가
j = F[j]; // 다음 검색을 위해 점프
} else j++;
i++;
}
}
}
}
시간 복잡도 분석
KMP 알고리즘의 시간 복잡도는 O(n + m)이다. 여기서 n은 텍스트 T의 길이, m은 패턴 P의 길이이다. 실패 함수를 계산하는 데 O(m)의 시간이 소요되고, 검색 과정에서는 O(n)의 시간이 소요된다.
느낀점
KMP 알고리즘을 이용해 복잡한 문자열 검색 문제를 효율적으로 해결할 수 있었다는 점이 인상적이다. 불필요한 문자 비교를 줄이는 실패 함수의 개념을 통해 문자열 검색의 효율성을 극대화할 수 있었다.
반응형
'알고리즘 > BOJ - Java' 카테고리의 다른 글
[BOJ/Java] 12015. 가장 긴 증가하는 부분 수열 2 (0) | 2024.04.25 |
---|---|
[BOJ/Java] 11055. 가장 큰 증가 부분 수열 (0) | 2024.04.25 |
[BOJ/Java] 9205. 맥주 마시면서 걸어가기 (0) | 2024.04.24 |
[BOJ/Java] 11726. 2xn 타일링 (0) | 2024.04.23 |
[BOJ/Java] 1463. 1로 만들기 (0) | 2024.04.23 |
Comments