N+1
개의 I
와 N
개의 O
로 이루어져 있으면, I
와 O
이 교대로 나오는 문자열을 PN
이라고 한다.
P1 IOI
P2 IOIOI
P3 IOIOIOI
PN IOIOI...OI (O가 N개)
I
와 O
로만 이루어진 문자열 S
와 정수 N
이 주어졌을 때, S
안에 PN
이 몇 군데 포함되어 있는지 구하는 프로그램을 작성하시오.
N
이 주어진다. 둘째 줄에는 S
의 길이 M
이 주어지며, 셋째 줄에 S
가 주어진다.S
에 PN
이 몇 군데 포함되어 있는지 출력한다.N = int(input()) # 2
M = int(input()) # 13
S = input() # "OOIOIOIOIIOII"
cursor, count, result = 0, 0, 0
while cursor < (M - 1): # cursor가 M-1 보다 작을 동안 실행 (끝까지)
if S[cursor:cursor + 3] == 'IOI': # 현재 위치부터 3글자를 잘라서 "IOI"인지 확인
count += 1 # IOI면 count + 1
cursor += 2 # cursor는 두칸 이동(I가 겹침)
if count == N: # IOI가 N번 연속해서 나오면 result + 1
result += 1
count -= 1 # 다음 패턴을 위해 하나 줄인다.(다음 IOI 체크)
else: # IOI가 아니면 cursor를 한 칸 이동한다.
cursor += 1
count = 0 # IOI 패턴이 끊기므로 count = 0 리셋
print(result)
cursor
, "IOI"
가 몇번나왔는지 세는 count
, 찾은 패턴의 개수를 나타내는 result
를 초기화해준다.count
에 1을 더해주고 cursor
는 두칸을 이동한다.count
가 N
번 연속해서 나오면 result
에 1을 더해주고 다음 IOI를 체크하기 위해 count
- 1을 한다.cursor
를 한칸 이동하고, count
는 IOI패턴이 끊기므로 0으로 리셋한다.result
출력N = int(input())
M = int(input())
S = input()
# 해쉬 값을 계산 하기 위한 준비물
mod = 1e9 + 7
po = [0] * M # 제곱한 값들 저장 배열
po[0] = 1 # 31^0 = 1 이기 때문에 1로 설정
for i in range(1, M):
po[i] = po[i - 1] * 31 % mod # 이전 값에 31 곱하고 mod 나머지 연산
# Pn 만들기
Pn = "I"
for i in range(N):
Pn += "OI"
# Pn의 해쉬값 계산
# 0에서 시작해서 매번 한자리씩 올림을 하고 현재 자릿수를 더해준다.
Pn_hash = 0
for i in range(len(Pn)):
Pn_hash *= 31
Pn_hash %= mod
# A를 1로 했을 때 알파벳 값을 구하기 위해 ASCII 코드로 계산하면 I,O의 값을 알 수 있다.
Pn_hash += ord(Pn[i]) - ord('A') + 1
Pn_hash %= mod
# S[0:len(Pn)] S의 맨 처음 부분문자열은 무조건 계산해줘야 한다.(값을 다른데서 가져올 수 없음)
S_hash = 0
for i in range(len(Pn)):
S_hash *= 31
S_hash %= mod
S_hash += ord(S[i]) - ord('A') + 1
S_hash %= mod
# S의 부분 문자열들의 해쉬 값 계산
count = 0 # 답 출력 카운트
for i in range(0, M - len(Pn) + 1):
if S_hash == Pn_hash:
count += 1
# S_hash 갱신
# (OIOIO - 15*31^4)
largest = ord(S[i]) - ord('A') + 1
S_hash += mod - largest * po[len(Pn) - 1] % mod
S_hash %= mod
# 한자리수 올림
S_hash *= 31
S_hash %= mod
# 새로 오는 알파벳 더해줌
# 맨 마지막은 새로 갱신할 필요없어서 맨 마지막 전까지 갱신
if i + len(Pn) < M:
S_hash += ord(S[i + len(Pn)]) - ord('A') + 1
S_hash %= mod
print(count)
해쉬
를 이용한 풀이이다.
해쉬
개념을 공부해서 풀이를 해보려고 했지만 막상 어려워서 풀이를 보고 코드만 이해했다. 😂