[알고리즘] Swift -백준 #1302 (베스트셀러) -딕셔너리정렬

2022. 8. 13. 02:14ALGORITHM/Swift

728x90
반응형

문제링크

https://www.acmicpc.net/problem/1302

 

1302번: 베스트셀러

첫째 줄에 오늘 하루 동안 팔린 책의 개수 N이 주어진다. 이 값은 1,000보다 작거나 같은 자연수이다. 둘째부터 N개의 줄에 책의 제목이 입력으로 들어온다. 책의 제목의 길이는 50보다 작거나 같고

www.acmicpc.net

 

문제

김형택은 탑문고의 직원이다. 김형택은 계산대에서 계산을 하는 직원이다. 김형택은 그날 근무가 끝난 후에, 오늘 판매한 책의 제목을 보면서 가장 많이 팔린 책의 제목을 칠판에 써놓는 일도 같이 하고 있다.

오늘 하루 동안 팔린 책의 제목이 입력으로 들어왔을 때, 가장 많이 팔린 책의 제목을 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 오늘 하루 동안 팔린 책의 개수 N이 주어진다. 이 값은 1,000보다 작거나 같은 자연수이다. 둘째부터 N개의 줄에 책의 제목이 입력으로 들어온다. 책의 제목의 길이는 50보다 작거나 같고, 알파벳 소문자로만 이루어져 있다.

출력

첫째 줄에 가장 많이 팔린 책의 제목을 출력한다. 만약 가장 많이 팔린 책이 여러 개일 경우에는 사전 순으로 가장 앞서는 제목을 출력한다.

 

 


분석

김형택씨는 캐셔다

오늘 판매한 책의 제목을 보면서 가장 많이 팔린책의 제목을 칠판에 쓴다

하루 동안 팔린 책의 제목이 입력으로 들어갔을 때

가장 많이 팔린 책의 제목을 출력하라

 

풀이과정

딕셔너리에 넣어서 키값을 책이름으로 주고 반복횟수를 밸류값에 넣어 +1을 해준다

마지막에 밸류의 값이 가장 큰 키 값을 찾는다.

가장 큰 값이 여러개일 경우에는 사전 순으로 (오른차순)인 한개만! 출력한다.

 

 

풀이

let num = Int(readLine()!)!
var dic = [String : Int]()

for _ in 0..<num {
    let input = readLine()!
    if dic.keys.contains(input) {
        dic[input]! += 1
    } else {
        dic[input] = 1
    }
}
let dic2 = dic.keys.sorted()
var max = 0
var maxName = ""
for i in dic2 {
    if max < dic[i]! {
        max = dic[i]!
        maxName = i
    }
}
print(maxName)

 

결과

 

 

중요한 점

여기서 중요한 것은 딕셔너리의 밸류값으로 정렬했다고 해서 키값도 정렬되는 것은 아니다!!!!!!!!

let dic2 = dic.sorted {
    $0.1 > $1.1
}
print(dic2[0].key)

처음에 이렇게 시도했는데 틀려버렸다 ㅎㅎ

그래서 먼저 키값을 사전순으로 (오름차순으로) 정렬한 후에 밸류값을 가장 큰 것을 찾아주는 것으로 변경했다.

let dic2 = dic.keys.sorted()
var max = 0
var maxName = ""
for i in dic2 {
    if max < dic[i]! {
        max = dic[i]!
        maxName = i
    }
}
print(maxName)

더 쉬운 방법이 있다는 사실을 깨달아버렸지 뭐람

아니 이걸 한 줄로 해결이 가능하다.

정렬을 하는데 그에 맞는 조건을 설정해준다.

 

let dic2 = dic.sorted() {
    $0.value == $1.value ? $0.key < $1.key : $0.value > $1.value
}
print(dic2.first!.key)

밸류값을 비교해서 같다면 (같은 밸류값을 가지고 있다면 == 최다 판매 책이 여러개 일 경우)

 키의 값을 오름차순으로 

더보기

$0.key < $1.key : 내림차순 (사전 반대순)

$0.key > $1.key : 오름차순 (사전 순)

아니면 (밸류값이 같지 않으면 최다 판매 책이 하나 !)

그냥 밸류값 순으로 정렬한다.

그리고 정렬한 딕셔너리에 가장 처음의 키값을 출력한다.

(숫자 정렬이랑 문자 정렬이랑 왜 이렇게 헷갈리는 지 정말... 후하후하)

 

다른 풀이

let N = Int(readLine()!)!
var nameToCnt = [String: Int]()

for _ in 0..<N {
    nameToCnt[readLine()!, default: 0] += 1
}

print(nameToCnt.sorted{$0.value != $1.value ? $0.value > $1.value : $0.key < $1.key}[0].key)

이렇게 더 간단하게도 가능하다

어차피 키 값은 중복이 가능하지 않기 때문에 그냥  초기값을 정해주고 들어오는 것의 밸류값을 +1 해주면 된다!!

기억하자 딕셔너리도 키는 중복이 되지 않는다는 것을..

 

 

 

 

 

 

728x90
반응형