티스토리 뷰

문제

https://school.programmers.co.kr/learn/courses/30/lessons/17677

풀이

  1. 2글자 씩 잘라서 다중집합을 생성
  2. 다중집합을 생성하면서 영문자를 제외한 문자(띄어쓰기 포함)를 포함한 경우는 제외
  3. 소문자, 대문자는 대문자로 저장(대,소문자를 구별하지 않기 위함)
  4. 교집합을 구함(두 다중집합을 정렬해서 비교)
  5. 합집합을 구함(두 다중집합을 합치고 교집합의 요소를 한번씩 뺌
  6. 결과는 3가지 종류로 나눌 수 있음
    • 합집합이 공집합인 경우 : 공집합의 개수로 나눌 수 없으니 유사도는 1
    • 합집합이 공집합은 아니지만 교집합이 공집합인 경우 : 유사도는 0
    • 둘다 공집합이 아닌 경우 : 유사도는 (교집합의 개수 / 합집합의 개수)

전체코드



func makeArr(_ strs: [String]) -> [String] { // 한글자씩 담긴 배열을 넘기면 다중집합으로 만들어서 반환
    var result: [String] = []
    for idx in 0..<strs.count-1 {
        if ((strs[idx] >= "a" && strs[idx] <= "z") || (strs[idx] >= "A" && strs[idx] <= "Z")) && ((strs[idx+1] >= "a" && strs[idx+1] <= "z") || (strs[idx+1] >= "A" && strs[idx+1] <= "Z"))  { // 두 값이 알파벳 일떄만 추가
            result.append(strs[idx].uppercased()+strs[idx+1].uppercased()) // 값은 항상 대문자로 저장(대문자를 구별하지 않기 위함)
        }
    }
    return result.sorted()
}

func makeInter(_ arr1: [String], _ arr2: [String]) -> [String] { // 교집합 생성
    var arr1Idx: Int = 0
    var arr2Idx: Int = 0
    var result: [String] = []
    while arr1Idx < arr1.count && arr2Idx < arr2.count {
        if arr1[arr1Idx] < arr2[arr2Idx] {
            arr1Idx += 1
        }else if arr1[arr1Idx] > arr2[arr2Idx] {
            arr2Idx += 1
        }else { // 두값이 같은 경우
            result.append(arr1[arr1Idx])
            arr1Idx += 1
            arr2Idx += 1
        }
    }
    return result
}
func makeUnion(_ arr1: [String], _ arr2: [String], _ interSection: [String]) -> [String] { // 합집합 생성
    var result: [String] = (arr1 + arr2).sorted()
    for inter in interSection {
        let idx = result.firstIndex(of: inter)!
        result.remove(at: idx)
    }
    return result
}

func solution(_ str1:String, _ str2:String) -> Int {
    
    let str1Arr: [String] = makeArr(str1.map { String($0) })
    let str2Arr: [String] = makeArr(str2.map { String($0) })

    let interSection: [String] = makeInter(str1Arr, str2Arr)
    let union: [String] = makeUnion(str1Arr, str2Arr, interSection)
    
    if union.count == 0 { // 공집합으로 나눌 수 없으니 유사도 1
        return 65536
    }else if interSection.count == 0 { // 합집합은 공집이 아니라서 유사도 0
        return 0
    }
    return Int((Double(interSection.count) / Double(union.count)) * 65536)
}
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
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 31
글 보관함