반응형
안녕하세요. 개발 중인 정주입니다.
오늘은 "프로그래머스(Lv.2) - [1차] 뉴스 클러스터링" 문제를 풀었습니다.
Github
문제 링크
풀이
이번 문제는 중복이 허용 되는 집합 문제입니다.
원소의 중복이 허용되기 때문에 Set을 사용하지 못합니다.
Set을 사용할 수 있었으면 간편한 집합 연산 메서드로 쉽게 해결할 수 있었을 텐데 아쉽습니다.
1. 자카드 유사도에 사용할 다중 집합을 생성합니다.
이 과정에서 문자를 소문자로 대치하고 알파벳인지 확인하였습니다.
따라서 다중 집합에는 알파벳 소문자로만 이루어진 단어들만 존재합니다.
2. 교집합과 합집합을 생성합니다.
2-1. 교집합을 만드는 createIntersection()를 정의하였습니다.
2중 반복문을 이용해 두 집합에서 겹치는 원소만 추가합니다.
2-2. 합집합을 만드는 createUnion()을 정의하였습니다.
2중 반복문을 이용해 합집합을 빼주고 나머지 원소를 모두 추가하였습니다.
Swift에서 Array의 + 연산은 지원하지만 - 연산은 지원하지 않기 때문에 반복문을 이용해 제거 했습니다.
3. 결과를 계산하여 return 합니다.
소수 연산을 해야 하기 때문에 Double 연산을 합니다.
소수로 나온 몫을 65536.0을 곱한 뒤 소숫점을 버리고 Int로 변환하여 return 합니다.
if !(intersection.isEmpty && union.isEmpty) {
result = Double(intersection.count) / Double(union.count)
}
return Int(floor(result * MULTIPLE))
후기
교집합과 합집합을 직접 구현했다는 것에 의의가 있었습니다.
감사합니다!
전체 코드
import Foundation
let MULTIPLE: Double = 65536.0
func createStrArray(_ str: String) -> [String] {
let alphabet = "abcdefghijklmnopqrstuvwxyz"
let str = Array(str).map { String($0) }
var results: [String] = []
for i in 0..<str.count-1 {
let ch1 = str[i].lowercased()
let ch2 = str[i+1].lowercased()
guard alphabet.contains(ch1), alphabet.contains(ch2) else {
continue
}
results.append(ch1 + ch2)
}
return results
}
func createIntersection(_ arr1: [String], _ arr2: [String]) -> [String] {
var result: [String] = []
var temp = arr2
arr1.forEach {
if let index = temp.firstIndex(of: $0) {
temp.remove(at: index)
result.append($0)
}
}
return result
}
func createUnion(_ arr1: [String], _ arr2: [String]) -> [String] {
var result: [String] = []
var temp = arr2
arr1.forEach {
if let index = temp.firstIndex(of: $0) {
temp.remove(at: index)
}
}
result.append(contentsOf: arr1)
result.append(contentsOf: temp)
return result
}
func solution(_ str1:String, _ str2:String) -> Int {
var result: Double = 1.0
let str1Arr: [String] = createStrArray(str1)
let str2Arr: [String] = createStrArray(str2)
let intersection: [String] = createIntersection(str1Arr, str2Arr) //교집합
let union: [String] = createUnion(str1Arr, str2Arr) //합집합
if !(intersection.isEmpty && union.isEmpty) {
result = Double(intersection.count) / Double(union.count)
}
return Int(floor(result * MULTIPLE))
}
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.
반응형