programmers.co.kr/learn/courses/30/lessons/12926
안녕하세요 후르륵짭짭 입니다
이번에는 시저 암호라는 문제를 풀어 봤는데요.
C++이나 JAVA에 비해 Swift의 약점인 String 문자 변경에 대해서 다뤄 볼려고 합니다!
처음에는 이렇게 풀었습니다.
func solution(_ s:String, _ n:Int) -> String {
var answer : String = ""
let z = UInt8( UnicodeScalar("z").value )
let Z = UInt8( UnicodeScalar("Z").value )
let convertList = s.map { (char) -> String in
var temp : String = String(char)
if ("a"..."z").contains(char){
let number = char.asciiValue! + UInt8(n)
if number > z {
temp = String(UnicodeScalar( 96 + UInt8(number - z) ))
}
else{
temp = String(UnicodeScalar( char.asciiValue! + UInt8(n) ))
}
}
else if ("A"..."Z").contains(char){
let number = char.asciiValue! + UInt8(n)
if number > Z {
temp = String(UnicodeScalar( 64 + UInt8(number - Z) ))
}
else {
temp = String(UnicodeScalar( char.asciiValue! + UInt8(n) ))
}
}
return temp
}
for item in convertList{
answer += item
}
return answer
}
그럼 하나 씩 알아보도록 하겠습니다.
** 문자열을 아스키코드로 변경하기 **
Swift에서는 문자열 하나를 아스크코드로 변경 할 수가 없습니다.
따라서 UnicodeScalar("문자열").value로 해줘야 합니다.
let Z = UInt8( UnicodeScalar("Z").value )
그래서 아스키코드 번호가 나옵니다.
아니면 변수에 문자 하나를 담고 그 문자에서 asciiValue 를 해줘야합니다.
그리고 계산을 하려면 UInt8 형태로 해줘야합니다.
let number = char.asciiValue! + UInt8(n)
** 문제 해결 **
z => 122
Z => 90
이렇게 됩니다.
만약에 "B" + 25를 하게 된다면 66 + 25 = 91 이 됩니다.
엄청나게 오버 하게 되죠 ㅎㅎㅎ
그래서 91 - 90 을 빼주면 1 이 남게 됩니다.
즉, Z에서 한 칸 더 움직인거다. 라는 의미가 되기 때문에 64에서 뺀수를 더해주는 겁니다.
** 더 좋은 방법 **
풀면서 먼가 만족 스럽지 않았습니다.
그래서 다른 사람의 코드를 봤습니다.
func solution2(_ s:String, _ n:Int) -> String {
let answer = s.utf8.map { (codeUInt) -> String in
var number = Int(codeUInt)
if (65...90).contains(number){
number = (number + n - 65 ) % 26 + 65
}
else if (97...122).contains(number){
number = (number + n - 97 ) % 26 + 97
}
return String(UnicodeScalar(number)!)
}
return answer.joined()
}
이렇게 문제를 해결 한 것인데,
일단 문자열을 utf8 형태로 변경 해주고 거기서 고차함수 map을 해줍니다.
그런 다음 number 가 소문자에 해당하는지 대문자에 해당하는지 구별 해줍니다.
그런 다음 결국 위의 저의 해결 방법과 같아 집니다.
만약 "B" + 25 를 해서 91 이 되고 거기서 65를 빼준다는 의미는 "A"에서 "B"가 얼마나 떨어져 있냐를 확인 해 줍니다.
따라서 "A"에서 몇칸 앞에 있는가를 찾을 수 있져
그럼 26칸 이동한 것이 확인이 되고 여기서 26을 나눠주면 0 + 65 를 해주면
즉 A가 나오게 됩니다.
이 풀이를 보고 새롭게 알게 된 것은
문자열을 utf8으로 변경해서 아스키코드로 모두 한번에 변경이 되는 것을 알게 되었고
문자열 배열로 된 것을 String으로 한번에 묶어 주기 위해서는 joined()를 써주면 된다는 것도
처음 알았습니다.
'Xcode > Swift - Algorithm' 카테고리의 다른 글
Swift) LeetCode(Easy) - Palindrome Linked List(Linked List) (0) | 2020.07.19 |
---|---|
Swift) LeetCode(Easy) - Merge Two Sorted Lists(Linked List) (0) | 2020.07.19 |
Swift) 프로그래머스(Lv1) 수박수박수박수박수? (String) (0) | 2020.07.13 |
Swift) LeetCode(Easy) - Best-Time-To-Buy-And-Sell-Stock(DP) (0) | 2020.07.13 |
Swift) LeetCode(Easy) - Climbing Stairs (DP) (0) | 2020.07.13 |
댓글