-
가장 많이 받은 선물 -1-iOS 앱 개발 부트캠프/TIL 2024. 11. 9. 18:20
문제
음.. 내용이 뭔가 많다. 한 줄 씩 찬찬히 읽어보자.
두 사람씩 비교를 한다. A와 B 두 사람의 선물 주고받은 횟수를 비교하여, 횟수가 더 많은 사람이 받는 선물의 개수가 +1이 된다.
이 과정을 모든 친구들과 비교하면 되고, 두 사람이 선물을 주고받은 기록이 없거나 횟수가 같다면 선물 지수를 비교해 선물 지수가 큰 사람이 받는 선물의 개수가 +1이 된다.
선물 지수는 주고받은 모든 선물 기록을 토대로, 선물을 줬으면 선물지수가 +되고, 받았으면 -되는 식으로 계산한다.
선물지수까지 같다면 선물을 주고 받지 않는다.
그렇다면 입력으로 들어가는 friends와 gifts는 어떤 형식일까? 입력 값을 문제의 예시에서 확인해보자.
friends엔 이름 한 단어씩 하나의 원소로 들어가 있고, gifts엔 두 사람의 이름이 공백으로 띄워져 하나의 원소로 들어가 있다.
for-in문으로 gifts의 각 원소를 뽑아 공백을 기준으로 선물 준 사람과 선물 받은 사람을 세고, 받은 사람이 몇 번 받았는지 카운트 할 수 있다면,
이걸 [String: [String : Int]] 형태의 이중 딕셔너리를 만들면, A가 B,C,D...에게 몇 번 선물을 줬는지, 반대로 B,C,D...가 A에게 몇 번 선물을 줬는지 각각 저장해 접근할 수 있을 것 같다.
코드 작성
1. 이중 딕셔너리 생성
func solution(_ friends:[String], _ gifts:[String]) -> Int { // 이름을 키로 하는 이중 딕셔너리 생성 var giftRecord: [String : [String:Int]] = [:] for friend in friends { giftRecord["\(friend)"] = [:] } print("giftRecord :", giftRecord)
일단 friends의 각 요소인 이름을 하나씩 뽑아 이를 키로 하는 딕셔너리를 만들었다. 이렇게 하면 다음과 같은 결과가 나온다.
giftRecord는 이중 딕셔너리로, [선물 준 사람 : [선물 받은 사람 : 받은 횟수]] 형태가 될 것이다. 따라서 지금 상태는 선물 준 사람을 키로 하고, 밸류인 [받은 사람 : 받은 횟수] 딕셔너리는 내용 없이 초기화만 되어 있는 상태이다.
2. 선물 준 사람, 선물 받은 사람 구분하기
이제 반복문을 이용해 여기에 값을 넣어 줄 것이다.
for record in gifts { let splitRecord = record.components(separatedBy: " ") let giver = splitRecord[0] // 선물 준 사람 let reciver = splitRecord[1] // 선물 받은 사람
일단 gifts의 요소를 가져와 공백을 기준으로 나눈다.
components는 배열을 반환하므로 splitRecord에는 [선물 준 사람, 선물 받은사람] 형태로 되어 있을 것이다. splitRecord의 0번 인덱스 값을 giver에, 1번 인덱스 값을 reciver에 넣어주면 선물 준 사람과 받은 사람을 구분할 수 있게 된다.
3. 딕셔너리에 선물 주고 받은 횟수 저장하기
giftRecord[giver]?[reciver, default: 0] += 1 // [받은 사람: 받은 횟수] 딕셔너리에 키를 reciver로 하는 딕셔너리의 밸류(receiver의 받은 횟수) +1 하기 print("\(giver)가 \(reciver)에게 준 선물 횟수 :", giftRecord[giver]?[reciver] ?? 0) } print("giftRecord", giftRecord)
giftRecord[giver]는 이중 딕셔너리인 giftRecord에 giver(선물 준 사람)라는 키에 해당하는 밸류를 찾는 것이다. 이 밸류는 [giver에게 선물 받은 사람 : 받은 횟수]인 딕셔너리이다.
이후 [receiver, default : 0] += 1은 하위 딕셔너리이자 이중 딕셔너리의 밸류인 [선물 받은 사람 : 받은 횟수] 딕셔너리 중에서 키가 receiver(선물 받은 사람)인 딕셔너리를 찾아 그 딕셔너리의 밸류(receiver가 선물 받은 횟수)를 +1 시키는 것이다.
default: 0은 receiver를 키로하는 딕셔너리가 없다면 해당 receiver를 키로하는 딕셔너리의 밸류를 0으로 설정한뒤 += 1을 하는 것인다. 잘못 다루면 선물 받은 적 없는 사람의 값이 추가 될 수 있지만 여기선 gifts의 요소인 "선물을준사람 선물을받은사람" 으로 되어 있는 걸 잘라 giver와 receiver로 설정하였기 때문에 문제 없을 것이다.
출력해보면 입력에 맞게 이중 딕셔너리의 값이 잘 추가된 것을 확인할 수 있다.
남은 부분
여기까지 하는데 오후가 다 갔다.. 이중 딕셔너리는 할 때마다 헷갈려서 계속 다시 작성하게 되는 것 같다.
이제 누가 누구에게 몇 번 선물했는지까지 했으니, 나머지는 두 사람간의 선물을 주고 받은 횟수 혹은 선물지수를 비교하여, 다음달엔 누가 누구에 줄 지 결정하고, 각 사람의 선물 횟수를 모두 더해 가장 많은 선물을 받을 사람을 찾으면 될 것이다.
'iOS 앱 개발 부트캠프 > TIL' 카테고리의 다른 글
가장 많이 받은 선물 -2- (1) 2024.11.10 자연수 뒤집기 알고리즘 (0) 2024.11.07 야구게임 만들기 - 2 (1) 2024.11.06 야구게임 로직 만들기 (5) 2024.11.05 약수의 합 (0) 2024.11.04