본문 바로가기

Mobile/Swift

[코딩테스트 입문] Swift - Day 9

반응형


1. 소인수분해
Q. 소인수분해란 어떤 수를 소수들의 곱으로 표현하는 것입니다. 예를 들어 12를 소인수 분해하면 2 * 2 * 3 으로 나타낼 수 있습니다. 따라서 12의 소인수는 2와 3입니다. 자연수 n이 매개변수로 주어질 때 n의 소인수를 오름차순으로 담은 배열을 return하도록 solution 함수를 완성해주세요.

I. 문제 파악하기
- 소인수를 찾는다.
- 오름차순으로 정렬한다.

A. 문제풀기

func solution(_ n:Int) -> [Int] {
    // 결과 담을 Container
    var result = [Int]()
    // 소인수분해 할 수
    var num = n
    // 나눌 값
    var x = 2

    while num != 1 {
        if num % x == 0 {
            num /= x
            result.append(x)
        } else {
            x += 1
        }
    }

    return Array(Set(result)).sorted(by: <)
}

(1) 나누는 값이 2부터 시작하는 것은 1은 소인수로 취급하지 않기 때문이다.

(2) 소인수분해 할 수가 더이상 정수로 나누어질 수 없는 수인 1이 될 때까지 반복해주어야 한다. 따라서 while문의 조건은 num이 1이 되지 않을 때까지 진행해주어야 한다.

(3) num과 x를 나누어서 나머지가 0이 되면 x는 num의 소인수가 된다. 따라서 결과값에 넣어주어야 한다.

(4) 나누어 떨어지지 않으면 x로는 더이상 나눌 수 없는 상태가 된다. x에 1을 더해 값을 높여준다. 여기서 x를 큰 수부터 내려오지 않고 작은 수부터 올라가는 이유는 소인수분해이기 때문이다. 만약 x 값을 n 값으로 두면 한번 나눔에 1이 되기 때문에 로직이 동작하지 않는다. 


2. 컨트롤 제트
Q. 숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다. 문자열에 있는 숫자를 차례대로 더하려고 합니다. 이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다. 숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요. 

I. 문제 파악하기
- 차례대로 더한다.
- n+1 번째에 Z가 나오면 n 번째 숫자는 지워진다.
- 공백을 기준으로 더한다.

A. 문제풀기

// 본인 답
func solution(_ s:String) -> Int {
    var stack = [Int]()
    s.components(separatedBy: " ").forEach {
        switch $0 {
        case "Z": stack.popLast()
        default: stack.append(Int($0)!)
        }
    }
    return stack.reduce(0, +)
}

map, filter, reduce로 해결하는 방법이 있지 않을까 한참 고민하다가 시간이 너무 오래 걸려서 풀어서 쓴 답안이 본인 답이다. 고차함수를 사용하려고 하다보니 풀어쓴 답도 그와 비슷한 모습인데, 결국 고차함수로는 해결하지 못했다.

그래서 forEach, switch, popLast 를 이용해서 문제를 해결했다.고차함수는 마지막에 reduce로 살짝 넣어주었다.


3. 중복된 문자 제거
Q. 문자열 my_string이 매개변수로 주어집니다. my_string에서 중복된 문자를 제거하고 하나의 문자만 남긴 문자열을 return하도록 solution 함수를 완성해주세요.

I. 문제 파악하기
- 문자열을 한 단어씩 불러온다.
- 불러온 단어를 다른 Container 문자열에 담아둔다.
- Container 문자열에 담을 때, 이미 있는 문자열인지 확인 후 담는다.
- 완성된 Container를 반환한다.

A. 문제풀기

func solution(_ my_string:String) -> String {
    var container = ""
    my_string.map { if container.contains($0) == false { container+=String($0) } }
    return container
}
func solution(_ my_string:String) -> String {
    var container = ""
    my_string.forEach { if container.contains($0) == false { container+=String($0) } }
    return container
}

split 함수를 사용해서 문자열을 분리하니 어째서인지 플레이그라운드에서는 분리가 되는데 프로그래머에서는 분리가 되지 않았다. 그래서 조금 더 간단하게 분리할 수 있는 map 함수와 forEach 함수를 사용했다. map 함수는 다시 리스트를 반환하는 함수이기 때문에 본인 생각에는 forEach 가 더 맞는 방법인 거 같다.


 

반응형