IOS/Swift Algorithm Level 1

Swift. 시저 암호

시저 암호

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 AB는 1만큼 밀면 BC가 되고, 3만큼 밀면 DE가 됩니다. z는 1만큼 밀면 a가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

제한 조건

  • 공백은 아무리 밀어도 공백입니다.
  • s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
  • s의 길이는 8000이하입니다.
  • n은 1 이상, 25이하인 자연수입니다.

func solution(_ s:String, _ n:Int) -> String {
    let lower = Array("abcdefghijklmnopqrstuvwxyz")
    let upper = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    var arr = Array(s)

for i in 0..<arr.count {
    if lower.contains(arr[i]) {
        let index = (lower.firstIndex(of: arr[i])!+n)%26
        arr[i] = lower[index]
    } else if upper.contains(arr[i]) {
        let index = (upper.firstIndex(of: arr[i])!+n)%26
        arr[i] = upper[index]
    }
}
    return String(arr)
}

요구사항. 

  1. 맨처음 알파벳을 기준을 어떻게 만들어야 할지 고민했다. 유니코드라던지 아니면 알파벳 배열이라던지
  2. 그다음에는 어떻게 해당 문자열에서 알파벳의 위치를 가져올지를 생각했고
  3. 해당 인덱스를 어떻게 교체할지를 생각했다
  4. 위의 코드를 보면 맨처음에는 z의 인덱스에서 +n을 하면 자구 out of range가 발생해서 어떻게 할지 고심하다가 % 26을 하게 되었다

인상적인 풀이

func solution(_ s:String, _ n:Int) -> String {
    let alphabets = "abcdefghijklmnopqrstuvwxyz".map { $0 }
    return String(s.map {
        guard let index = alphabets.firstIndex(of: Character($0.lowercased())) else { return $0 }
        let letter = alphabets[(index + n) % alphabets.count]
        return $0.isUppercase ? Character(letter.uppercased()) : letter
    })
}
  • 내가 작성한 코드와 비슷한 방식이지만 map을 썻다는 점에서 조금 다르다
  • guard 를 통해서 nil 값을 방어해주고 (문자열의 자리가 공백인경우 nil)
  • 마지막에 대문자 판별 isUppercase 를 사용해서 대문자인경우 uppercased()로 만들어서 통과했다
    • 아직 문자열에대해서 좀더 배워야 겠다고 생각했고 map의 활용도를 높여야 겠다.

'IOS > Swift Algorithm Level 1' 카테고리의 다른 글

Swift. 이상한 문자 만들기  (0) 2020.10.21
Swift. 약수의 합  (0) 2020.10.20
Swift. 문자열을 정수로 바꾸기  (0) 2020.10.18
Swift. 수박수박수...  (0) 2020.10.17
Swift. 소수 찾기  (0) 2020.10.16