요약 | 알파벳 목록에서 특정 문자를 뺐을 때, 주어지는 문자열의 알파벳 위치에서 index 숫자만큼 밀어낸 암호문 결과를 출력하라.
class Solution { fun solution(s: String, skip: String, index: Int): String { var answer: String = "" s.forEach { it -> var skipCnt = 0 skip.forEach { skipThis -> if (it.toInt() < skipThis.toInt() && skipThis.toInt() < it.toInt() + index) { skipCnt++ } } if (it.toInt() + index + skipCnt > 122) { answer += ((it.toInt() + index + skipCnt) - 26).toChar() } else { answer += (it.toInt() + index + skipCnt).toChar() } } return answer } }
목표는
1. s의 char에 하나씩 접근(it)
2. it의 아스키값 ~ it아스키값+index값 사이에 skip의 아스키값이 몇 개 포함되는지 확인한다.
3. it의 아스키값 + index + 포함하고 있는 skip 개수를 한다.
3-1. 이때 %26하여 알파벳 범위를 벗어나면 다시 a부터 시작하도록 한다.
였으나.. 정상 작동 하지 못 하였다.
특히 "yyyy" 문자를 "za"를 스킵하고 2씩 인덱스가 넘어간 결과를 받고싶다고 했을 때, 제대로 처리를 못 하였다. 이런 케이스에서는 skipCnt를 특수하게 처리를 해주어야겠다 싶어서 수정을 해봤고,
class Solution { fun solution(s: String, skip: String, index: Int): String { var answer: String = "" s.forEach { it -> var skipCnt = 0 skip.forEach { skipThis -> if (it.toInt() + index > 122) { var temp = 0 skip.forEach { i -> if (it.toInt() < i.toInt() && i.toInt() <= 122) { temp ++ } } skipCnt = 122 + temp - it.toInt() } else { if (it.toInt() < skipThis.toInt() && skipThis.toInt() < it.toInt() + index) { skipCnt++ } } } if (it.toInt() + index + skipCnt > 122) { answer += ((it.toInt() + index + skipCnt) - 26).toChar() } else { answer += (it.toInt() + index + skipCnt).toChar() } } return answer } }
이런 코드가 나왔으나,,, 막상 제출하면 모두 fail..!
문제를 너무 복잡하게 접근하고 있다는 생각이 들었고 처음부터 풀자고 생각했지만.. 당최 어떻게 풀어야할지 감이 오지 않아 이번에는 로직 서치를 하여 도움을 받았다.
class Solution { fun solution(s: String, skip: String, index: Int): String { var answer: String = "" val alphabets = ('a'..'z').filter { !skip.contains(it) }.sorted() val alphaLength = alphabets.size s.forEach { answer += alphabets[(alphabets.indexOf(it) + index) % alphaLength] } return answer } }
alphabets = ('a'..'z').filter { !skip.contains(it) }.sorted()
: 알파벳 a~z 중에 filter하여 skip에 포함하고 있는 문자는 제외하고 저장한다. 이때 오름차순으로 정렬하여 정제된 알파벳 목록을 저장한다.alphaLength = alphabets.size
: index를 더했을 때에 z를 넘어가는 경우에 대비하기 위해 정제된 알파벳 목록의 길이 값을 기억해둔다.- forEach문으로 각 문자를 돌면서,
(alphabets.indexOf(it) + index) % alphaLength
: 해당 문자가 정제된 알파벳 리스트에서 몇 번째에 있는지 확인하고 그 값에 index를 더한다. z를 넘어갈 수 있으므로 정제된 알파벳 리스트 길이로 나누고 나머지 값을 취한다. 이게 바로 암호문 결과의 인덱스 값이 된다.answer += alphabets[...]
위에서 취한 인덱스 값을 정제된 알파벳 리스트에서 찾아 결과에 적립한다.
[TIL-240321]