코딩 테스트에 자주 출제되는 알고리즘 문제를 다루며, 그 문제를 해결하는 과정을 심층적으로 설명합니다. 오늘의 주제는 ‘DNA 비밀번호’로, DNA 문자열을 기반으로 한 비밀번호 문제를 해결해보겠습니다.
문제 설명
당신은 DNA 문자열을 이용하여 비밀번호를 생성하는 시스템을 설계해야 합니다. DNA 문자열은 대문자 A, C, G, T로 이루어져 있으며, 각 문자들은 다양한 조합으로 비밀번호의 구성 요소가 됩니다.
입력으로 주어진 DNA 문자열에서 특정 패턴을 찾고, 이 패턴에 대한 비밀번호를 생성해야 합니다. 다음은 구체적인 문제 정의입니다:
문제 정의
주어진 문자열 s
와 자연수 k
가 입력으로 주어질 때, s
에서 길이가 k
인 모든 부분 문자열을 고려하고, 이러한 부분 문자열이 갖는 A, C, G, T의 빈도수를 사용하여 비밀번호를 생성해야 합니다.
비밀번호는 최소한 A, C, G, T 각각의 빈도수가 min_count
이상인 부분 문자열의 개수를 세는 방식으로 정의합니다.
입력 예시
s = "ACGTACGTGACG", k = 4, min_count = 1
출력 예시
3
여기서 “ACGT”, “CGTA”, “GTAC”는 빈도수가 각각 1 이상인 부분 문자열입니다.
문제 해결 전략
이 문제를 해결하기 위한 전략은 다음과 같습니다:
- 전체 문자열
s
에서 길이가k
인 부분 문자열을 생성합니다. - 각 부분 문자열의 A, C, G, T 빈도수를 계산합니다.
- A, C, G, T 빈도수가
min_count
이상이면 카운트를 증가시킵니다. - 최종적으로 카운트를 출력합니다.
구현 단계
이제 스위프트를 사용하여 문제를 구현하는 방법을 살펴보겠습니다. 다음은 문제를 해결하기 위한 단계별 코드입니다.
1. 입력 받기
우선 문자열과 변수를 입력받습니다. 스위프트에서는 명령줄 인수나 직접 입력을 통해 값을 받을 수 있습니다.
let inputString = "ACGTACGTGACG"
let k = 4
let minCount = 1
2. 부분 문자열 생성
문자열에서 길이가 k
인 모든 부분 문자열을 생성합니다.
var count = 0
let length = inputString.count
for i in 0...(length - k) {
let startIndex = inputString.index(inputString.startIndex, offsetBy: i)
let endIndex = inputString.index(startIndex, offsetBy: k)
let substring = String(inputString[startIndex..
3. 빈도수 계산
생성된 부분 문자열에 대해 각 문자(A, C, G, T)의 빈도수를 계산합니다.
var frequencies = [Character: Int]()
for char in substring {
frequencies[char, default: 0] += 1
}
// 조건 확인
if frequencies["A"]! >= minCount &&
frequencies["C"]! >= minCount &&
frequencies["G"]! >= minCount &&
frequencies["T"]! >= minCount {
count += 1
}
4. 결과 출력
최종 카운트를 출력합니다.
print("총 유효한 비밀번호 개수: \(count)")
전체 코드
이제 모든 단계를 통합한 전체 코드를 확인해 보겠습니다.
let inputString = "ACGTACGTGACG"
let k = 4
let minCount = 1
var count = 0
let length = inputString.count
for i in 0...(length - k) {
let startIndex = inputString.index(inputString.startIndex, offsetBy: i)
let endIndex = inputString.index(startIndex, offsetBy: k)
let substring = String(inputString[startIndex..= minCount &&
frequencies["C"]! >= minCount &&
frequencies["G"]! >= minCount &&
frequencies["T"]! >= minCount {
count += 1
}
}
print("총 유효한 비밀번호 개수: \(count)")
결과
주어진 입력에 대해 이 코드를 실행하면, 유효한 비밀번호의 개수가 출력됩니다. 이처럼 문자열을 처리하고 조건을 확인하는 기본적인 알고리즘 패턴을 이해하는 것은 코딩 테스트에서 매우 유용합니다.
나아가 다양한 입력 케이스에 대해 코드를 테스트하고, 예외 처리를 추가하는 등의 작업을 통해 문제 해결 능력을 더욱 향상시킬 수 있습니다.