본문 바로가기
Xcode/Swift - Algorithm

Swift) 프로그래머스(Lv2) - [1차] 뉴스 클러스터링 (Hash)

by 후르륵짭짭 2020. 9. 6.
728x90
반응형

programmers.co.kr/learn/courses/30/lessons/17677

 

코딩테스트 연습 - [1차] 뉴스 클러스터링

뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브��

programmers.co.kr

안녕하세요 후르륵짭짭 입니다

이번에는 2018 카카오 블라인드 문제인 뉴스 클러스터링을 가져왔습니다.

이 문제만 읽는다고 풀 수 있는게 아니라,,, 하나씩 직접 만들어봐야 했습니다.

 

이렇게 하나씩 고려 해봐야 했습니다.

 

** 문제 해설 **

// 46 : 57
func solution(_ str1:String, _ str2:String) -> Int {
    
    let new1 = Array(str1.lowercased())
    let new2 = Array(str2.lowercased())
    
    var stack1 : [String : Int] = [:]
    var stack2 : [String : Int] = [:]
    
    var index = 0
    
    while index < new1.count - 1 {
        
        if new1[index].isLetter && new1[index + 1].isLetter {
        
        let word = String(new1[index]) + String(new1[index + 1])
            
        
        if let exist = stack1[word] {
            stack1[word] = exist + 1
        }
        else{
            stack1[word] = 1
        }
            
        }
        
        index += 1
    }
    
    index = 0
    
    while index < new2.count - 1 {
          
        if new2[index].isLetter && new2[index + 1].isLetter {
        
          let word = String(new2[index]) + String(new2[index + 1])
              
          
          if let exist = stack2[word] {
              stack2[word] = exist + 1
          }
          else{
              stack2[word] = 1
          }
            
        }
          
          index += 1
      }
    
    print(stack1)
    print(stack2)
    
    var same : Int = 0
    var all : Int = 0
    
    for element in stack1 {
        
        if let exist = stack2[element.key]{
            same += min(element.value , exist)
            all += max(element.value, exist)
            stack2.removeValue(forKey: element.key)
        }else{
        
        //교집합이 되지 않은 stack1
        all += element.value
            
        }
        
    }
    
    
    for element in stack2 {
        all += element.value
    }
    
    print(same)
    print(all)
    
    if same == 0 && all == 0 {
        return 65536
    }
    
    return  Int((Double(same) / Double(all)) * 65536)
}

전체적인 저의 코드 입니다...

엄청 길죠,,,, 하나씩 보도록 하겠습니다.

let new1 = Array(str1.lowercased())
let new2 = Array(str2.lowercased())
    
var stack1 : [String : Int] = [:]
var stack2 : [String : Int] = [:]
    
var index = 0


while index < new1.count - 1 {
        
        if new1[index].isLetter && new1[index + 1].isLetter {
        
        let word = String(new1[index]) + String(new1[index + 1])
            
        
        if let exist = stack1[word] {
            stack1[word] = exist + 1
        }
        else{
            stack1[word] = 1
        }
            
        }
        
        index += 1
    }

이 코드는 ABCD 가 있을 때, AB / BC / CD 를 만들어 주는 코드 입니다.

그런데 만약에 AB+C+D 처럼 두쌍을 연결 했을 때, 문자가 아니라면 작업을 수행하지 않도록 했습니다.

그리고 딕셔너리인 stack을 활용해서 중복여부를 계산해줍니다.

    var same : Int = 0
    var all : Int = 0
    
    for element in stack1 {
        
        if let exist = stack2[element.key]{
            same += min(element.value , exist)
            all += max(element.value, exist)
            stack2.removeValue(forKey: element.key)
        }else{
        
        //교집합이 되지 않은 stack1
        all += element.value
            
        }
        
    }
    
    
    for element in stack2 {
        all += element.value
    }

그리고 교집합은 same , 합집합은 all 로 만들어주고

stack1의 내용을 확인 해줍니다. 그러면서 stack1의 내용을 stack2에도 가지고 있다면 

둘의 최소값을 same에 최대값은 all에 넣어줍니다.

그리고 stack2에 해당하는 key 값을 제거해줍니다!

(참고로 딕셔너리에서 해당 Key 값을 제거 할 때는 .removeValue(forKey: )를 이용해서 제거합니다. )

마지막으로 stack2에서 제거하고 남은 것은 stack2만 유일하게 가짓 것이니

그것을 합집합 all에 넣어주고 마지막 연산을 해주면 됩니다.

 

** 새로 알게 된 사실 **

let dictionary : [String : Int] = ["A":1 , "B":2 , "C":3 , "D":4]

let array = Array(dictionary).map { (element) -> Int in
    return element.value
} // 튜플의 형태로 저장된다.

let arraySet = Set(array)

print(arraySet)

 

이것은 그냥 dictionary에서 Array로 바꿀 수 있는지 실험을 한 것이다.

실험을 해보니 딕셔러니 자체를 Array로 바꾸면 (key: String , value: Int)형태로 튜플로 남게 된다.

그래서 하나의 값만 가져오기 위해서는 map으로 다시 새롭게 해줄 필요가 있다

아!!! 그리고 튜플 형태의 배열은 예상한 대로 Set이 되지 못한다.

따라서 하나의 값만 가질 수 있도록 map을 해줘야한다.

그러면 Set이 가능하다

728x90
반응형

댓글