[Swift - ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€] λ‰΄μŠ€ ν΄λŸ¬μŠ€ν„°λ§

2021. 5. 19. 17:32γ†πŸ§‘πŸ»‍πŸ’» iOS 개발/Swift - Algorithm - Solutions

 

문제 해석


 

Daum λ‰΄μŠ€μ˜ 개발 업무λ₯Ό 맑게 된 μ‹ μž…μ‚¬μ› νŠœλΈŒλŠ” λ‰΄μŠ€ 검색 문제점 κ°œμ„ μ„ 업무λ₯Ό λ§‘μ•˜λ‹€κ³  ν•©λ‹ˆλ‹€. μ‚¬μš©μžμ—κ²Œ λ”μš± λ‹€μ–‘ν•˜κ³  νŽΈλ¦¬ν•œ 검색 κ²°κ³Όλ₯Ό μ œκ³΅ν•˜κΈ° μœ„ν•΄ μžμΉ΄λ“œ μœ μ‚¬λ„λ₯Ό ν™œμš©ν•˜μ—¬ μœ μ‚¬ν•œ 기사듀을 λ¬Άμ–΄ μ œκ³΅ν•΄λ³΄κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

μžμΉ΄λ“œ μœ μ‚¬λ„λŠ” 집합 κ°„μ˜ μœ μ‚¬λ„λ₯Ό κ²€μ‚¬ν•˜λŠ” λ°©λ²•μœΌλ‘œ 두 μ§‘ν•©κ°„μ˜ κ΅μ§‘ν•©μ˜ 크기λ₯Ό 두 μ§‘ν•©κ°„μ˜ ν•©μ§‘ν•©μ˜ 크기둜 λ‚˜λˆˆ 값을 μ˜λ―Έν•©λ‹ˆλ‹€.

이 μžμΉ΄λ“œ μœ μ‚¬λ„λ₯Ό μ›μ†Œμ˜ 쀑볡을 ν—ˆμš©ν•˜λŠ” λ‹€μ€‘μ§‘ν•©μ—μ„œ ν™•μž₯μ‹œν‚€κ²Œ 되면 ꡐ집합은 두 집합 λͺ¨λ‘ ν¬ν•¨ν•˜λŠ” μ›μ†Œλ₯Ό μ΅œμ†Œ κ°œμˆ˜λ§ŒνΌμ„ ν¬ν•¨ν•˜κ³  합집합은 두 μ§‘ν•©μ—μ„œ ν¬ν•¨ν•˜λŠ” μ›μ†Œλ₯Ό μ΅œλŒ€ κ°œμˆ˜λ§ŒνΌμ„ ν¬ν•¨ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 두 닀쀑집합 A = { "AA", "AA", "AA", "BB"} , B = {"AA", "AA"} κ°€ μžˆλ‹€κ³  ν•΄λ΄…μ‹œλ‹€. 

κ·Έλ ‡κ²Œ 되면 두 λ‹€μ€‘μ§‘ν•©μ˜ ꡐ집합은 두 μ§‘ν•©μ—μ„œ 같이 λ“±μž₯ν•˜λŠ” "AA"의 μ΅œμ†Œ 포함 개수인 2만큼 κ°€μ§€κ²Œ 되고 합집합은 "AA"의 μ΅œλŒ€ λ“±μž₯ 개수인 3만큼 가지고 "BB"의 μ΅œλŒ€ λ“±μž₯ 회수인 1 만큼 κ°€μ§€κ²Œ λ©λ‹ˆλ‹€.

ꡐ집합 = { "AA", "AA" }

합집합 = { "AA", "AA" ,"AA", "BB" }

두 λ¬Έμžμ—΄μ„ μž…λ ₯ λ°›μ•„ μžμΉ΄λ“œ μœ μ‚¬λ„λ₯Ό κ΅¬ν•˜κ²Œ λ˜λŠ”λ° λ¬Έμžμ—΄μ„ 2λ¬Έμžμ”© λŠμ–΄μ„œ 닀쀑집합을 ν˜•μ„±ν•©λ‹ˆλ‹€.

λŒ€μ†Œλ¬Έμžλ₯Ό κ΅¬λ³„ν•˜μ§€ μ•Šκ³  μ•ŒνŒŒλ²³λ§Œ μ·¨κΈ‰ν•©λ‹ˆλ‹€. 두 집합 λͺ¨λ‘ 곡집합일 λ•ŒλŠ” μžμΉ΄λ“œ μœ μ‚¬λ„λ₯Ό 1둜 μ •μ˜ν•©λ‹ˆλ‹€.

문제 ν•΄κ²° & μ½”λ“œ


import Foundation

func solution(_ str1:String, _ str2:String) -> Int {
    // λŒ€μ†Œλ¬Έμžλ₯Ό κ΅¬λ³„ν•˜μ§€ μ•ŠκΈ° μœ„ν•΄ λŒ€λ¬Έμžλ‘œ ν†΅μΌν•©λ‹ˆλ‹€.
    // .map{$0}을 μ‚¬μš©ν•˜μ—¬ μΆ”ν›„ 두 λ¬Έμžμ”© λ¬Άμ–΄μ£ΌκΈ° μœ„ν•œ μž‘μ—…μ΄ νŽΈν•˜λ„λ‘ λ°°μ—΄λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.
    
    let capitalStr1 = str1.uppercased().map{$0}
    let capitalStr2 = str2.uppercased().map{$0}
    
    // ꡐ집합,합집합 λ°°μ—΄
    
    var intersection = [String]()
    var union = [String]()
    
    // νŠœν”Œμ˜ 첫 번째 값은 ν•΄λ‹Ή Key인 문자λ₯Ό Aμ—μ„œ ν¬ν•¨ν•˜λŠ” 개수이고
    // 두 번째 값은 Bμ—μ„œ ν¬ν•¨ν•˜λŠ” 개수λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.
    
    var countDict: Dictionary<String, (Int, Int)> = [:]
    
    // λŒ€λ¬Έμž μ•ŒνŒŒλ²³λ§Œ 필터링 ν•˜κΈ° μœ„ν•œ ν•¨μˆ˜
    
    func isAlphabet(_ character: Character) -> Bool {
        return character >= "A" && character <= "Z"
    }
    
    // μž…λ ₯받은 첫 번째 λ¬Έμžμ—΄μ„ 톡해 닀쀑 집합 Aλ₯Ό λ”•μ…”λ„ˆλ¦¬μ— μ €μž₯ν•©λ‹ˆλ‹€.
    // λ”°λΌμ„œ νŠœν”Œμ˜ 첫 번째 값에 포함 개수λ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.
    
    for idx in 0..<capitalStr1.count - 1 {
        
        if isAlphabet(capitalStr1[idx]) == false || isAlphabet(capitalStr1[idx+1]) == false {
            continue
        }
        
        let temp = "\(capitalStr1[idx])\(capitalStr1[idx+1])"
        
        // μ‘΄μž¬ν•˜λŠ” 경우 포함 개수 += 1, μ—†λŠ” 경우 (1, 0)
        
        if countDict[temp] != nil {
            countDict[temp]!.0 += 1
        } else {
            countDict[temp] = (1, 0)
        }
    }
    
    // μž…λ ₯받은 두 번째 λ¬Έμžμ—΄μ„ 톡해 닀쀑 집합 Bλ₯Ό λ”•μ…”λ„ˆλ¦¬μ— μ €μž₯ν•©λ‹ˆλ‹€.
    // λ”°λΌμ„œ νŠœν”Œμ˜ 두 번째 값에 포함 개수λ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.
    
    for idx in 0..<capitalStr2.count - 1 {
        if isAlphabet(capitalStr2[idx]) == false || isAlphabet(capitalStr2[idx+1]) == false {
            continue
        }
        
        let temp = "\(capitalStr2[idx])\(capitalStr2[idx+1])"
        
        if countDict[temp] != nil {
            countDict[temp]!.1 += 1
        } else {
            countDict[temp] = (0, 1)
        }
    }
    
    // λ”•μ…”λ„ˆλ¦¬κ°€ λΉ„μ–΄μžˆλŠ” 경우 A, B λͺ¨λ‘ 곡집합을 μ˜λ―Έν•˜λ―€λ‘œ 
    // μžμΉ΄λ“œ μœ μ‚¬λ„λ₯Ό 1둜 μ •μ˜ν•˜κ³  λ¦¬ν„΄ν•©λ‹ˆλ‹€.
    
    if countDict.isEmpty {
        return 1 * 65536
    }
    
    // λ”•μ…”λ„ˆλ¦¬λ₯Ό νƒμƒ‰ν•˜λ©° ν¬ν•¨κ°œμˆ˜λ₯Ό λΉ„κ΅ν•˜μ—¬ ꡐ집합과 합집합에 ν•΄λ‹Ή 문자λ₯Ό λ„£μ–΄μ€λ‹ˆλ‹€.
    
    for (key, value) in countDict {
        let maxVal = max(value.0, value.1)
        let minVal = min(value.0, value.1)
        for _ in 0..<maxVal {
            union.append(key)
        }
        for _ in 0..<minVal {
            intersection.append(key)
        }
    }
   
    return Int(Double(intersection.count)/Double(union.count) * 65536)
}