머리말
문제 링크
이 문제를 선택한 이유
- 구현 문제 연습
- 문자열
풀이
주의점
- 문제의 조건에서 a와 b의 길이가 최대 100,000인 점을 주의해야 한다.
- 단순히 문자열을 정수로 변환하여 더하면, 오버플로우에 의해 오류가 난다.
- 따라서 사람이 직접 계산하는 방식(혹은 논리회로에서 전가산기의 방식)으로 접근해야 한다.
- 숫자를 맨끝에서 더하면서 자리올림과 나머지를 나누어, 새로운 배열에 추가할 것이다.
풀이 순서
- 우선 파라미터의 값 중에 큰 수와 작은 수를 구분하여 각각 할당한다. (bigNumber, smallNumber)
- 문자열을 정수를 요소로 갖는 배열로 새로 할당한다(bigNumberArr, smallNumberArr)
- 각 자리를 더한 값의 배열(sumArrReversed, 끝에서 더하기에 순서가 반대)과 자리 올림(carry), 나머지(rest)를 초기화한다.
- 인덱스에 대한 반복문을 큰 숫자 배열의 맨 끝에서부터 맨앞까지 반복한다.
- 여기서 각 인덱스의 값과 자리 올림(carry, 기본값: 0)을 서로 더한다.
- 더한 값(sum) 중에 몫과 나머지를 구분하여 자리올림과 나머지를 구분하여 재할당한다.
- 이제 나머지를 더한 값의 배열에 하나하나 추가한다.
- 작은 숫자가 겹치지 않을 경우에는 3번 반복문에서 인덱스 초과가 나기 때문에 작은 숫자 배열의 인덱스가 끝나면 큰 숫자와 자리 올림만 더한다.
- 맨끝에 자리 올림이 남아 있을 수 있기 때문에 조건문을 더하여 자리올림이 남아 있을 경우 그 자리올림을 더한 값의 배열에 추가한다.
- 현재 구한 더한 값의 배열은 순서가 반대이기에, 뒤집은 이후 요소를 String으로 바꾸어 합쳐준다.
import Foundation
func solution(_ a:String, _ b:String) -> String {
var bigNumber: String = ""
var smallNumber: String = ""
if a.count >= b.count {
bigNumber = a
smallNumber = b
} else {
bigNumber = b
smallNumber = a
}
let bigNumberArr = bigNumber.map { Int(String($0))! }
let smallNumberArr = smallNumber.map { Int(String($0))! }
var sumArrReversed: [Int] = []
var carry: Int = 0
var rest: Int = 0
var j = smallNumberArr.count - 1
for i in stride(from:bigNumberArr.count-1, through: 0, by: -1) {
if j >= 0 {
var sum = bigNumberArr[i] + smallNumberArr[j] + carry
carry = sum / 10
rest = sum % 10
sumArrReversed.append(rest)
} else {
var sum = bigNumberArr[i] + carry
carry = sum / 10
rest = sum % 10
sumArrReversed.append(rest)
}
j -= 1
}
if carry != 0 { sumArrReversed.append(carry) }
return Array(sumArrReversed.reversed()).map { String($0) }.joined()
}
꼬리말
이중 인덱스 접근에 대한 어색함
- 분명 두 수를 더하는 방식은 이해가 갔지만, 부등호(>=)에서 등호(=)를 빼먹는 등의 사소한 실수로 계속 인덱스 초과가 떠서 아쉬웠다.
시간 초과(?)
- 처음에는 더한 값의 배열(sumArrReversed)이 아닌 큰 숫자 배열(bigNumberArr)과 작은 숫자 배열(smallNumberArr)을 먼저 뒤집었는데 시간 초과가 떴다…
- 문제의 원인이 무엇인지 다시 살펴봐야겠다.
// 시간 초과 풀이
import Foundation
func solution(_ a:String, _ b:String) -> String {
var bigNumber: String = ""
var smallNumber: String = ""
if a.count >= b.count {
bigNumber = a
smallNumber = b
} else {
bigNumber = b
smallNumber = a
}
let bigNumberReversed = Array(bigNumber.map { Int(String($0))! }.reversed())
let smallNumberReversed = Array(smallNumber.map { Int(String($0))! }.reversed())
var sumArrReversed: [Int] = []
var carry: Int = 0
var rest: Int = 0
for i in 0..<bigNumber.count {
if i < smallNumber.count {
var sum = bigNumberReversed[i] + smallNumberReversed[i] + carry
carry = sum / 10
rest = sum % 10
sumArrReversed.append(rest)
} else {
var sum = bigNumberReversed[i] + carry
carry = sum / 10
rest = sum % 10
sumArrReversed.append(rest)
}
}
if carry != 0 { sumArrReversed.append(carry) }
return Array(sumArrReversed.map { String($0) }.reversed()).joined()
}
'코딩 테스트 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] (Swift) 정수를 나선형으로 배치하기 (0) | 2023.06.05 |
---|---|
[프로그래머스] (Swift) [카카오 1차] 다트 게임 (0) | 2023.06.02 |
[프로그래머스] (Swift) 크기가 작은 부분 문자열 - Lv.1 (0) | 2023.05.11 |
[프로그래머스] (Swift) 카펫 - Lv.2 (0) | 2023.05.10 |
[프로그래머스] (Swift) 비밀지도 (2018 카카오 1차) - Lv.1 (0) | 2023.05.09 |
댓글