문제 설명
단어 s의 가운데 글자를 반환하는 함수, solution을 만들어 보세요. 단어의 길이가 짝수라면 가운데 두글자를 반환하면 됩니다.
제한사항
입출력 예
s | return |
---|---|
"abcde" | "c" |
"qwer" | "we" |
풀이 과정
- 문자열 s의 길이를 count 로 구해준다.
s.count
- s.count를 2로 나눠 중간 위치(middle)를 구한다.
- s가 짝수인 경우, 중간에 있는 앞뒤 문자를 추출한다.
- 앞 문자:
s[s.startIndex, offsetBy: middle - 1]
- 뒷 문자:
s[s.startIndex, offsetBy: middle]
- 홀수인 경우 중간 위치 문자를 추출한다.
-중간 문자:s[s.startIndex, offsetBy: middle]
- 반환된 문자,문자열을 String(…) 을 사용해 문자열로 변환해 반환한다.
(이 때 짝수인 경우와 홀수인 경우를 나누는 것은삼항연산자
로 표현한다.
(조건) ? (true일 경우 실행) : (false일 경우 실행)
)
startIndex
문자열의 시작지점 가리키는 인덱스offsetBy
현재 인덱스에서의 오프셋(이동거리)startIndex와 offsetBy를 함께 사용하면 현재 인덱스에서 주어진 오프셋만큼 이동한 새로운 인덱스를 얻을 수 있다.
//사용 예시 let word = "Bbang" let newIndex = word.index(startIndex, offsetBy: 2) print(word[newIndex]) // "b"
index(before:)
주어진 인덱스의 바로 이전 인덱스 가리키는 메서드//문자열 s의 중간 인덱스 구하고, 중간 이전 위치의 문자 인덱스 찾기 let middle = s.index(s.startIndex, offsetBy: s.count / 2) s.index(before: middle)
Solution
func solution(_ s: String) -> String {
let middle = s.count / 2
return s.count % 2 == 0 ? String(s[s.index(s.startIndex, offsetBy: middle - 1)...s.index(s.startIndex, offsetBy: middle)]) : String(s[s.index(s.startIndex, offsetBy: middle)])
}
func solution(_ s: String) -> String {
let middle = s.index(s.startIndex, offsetBy: s.count / 2)
return s.count % 2 == 0 ? String(s[s.index(before: middle)...middle]) : String(s[middle])
}
Another Solution
처음보는 endodedOffset 을 사용해서 간단하게 표현한 solution을 알게 되었다. 이 solution 에서는 홀수와 짝수를 나누지 않고 식을 작성할 수 있더라!! encodedOffset을 사용했기 때문이라고 하는데, 한 번 공부해보자!!
func solution(_ s:String) -> String {
return String(s[String.Index(encodedOffset: (s.count - 1) / 2)...String.Index(encodedOffset: s.count / 2)])
}
String.Index
문자열의 특정 인덱스를 나타내는 유형.
문자열을 인덱스로 탐색하고 특정 위치에서 문자열을 추출할 수 있다.이 solution에서는 [s.index(…)] 를 사용하지 않고,
String.Index(…)를 사용했다.
두 개의 차이를 살펴보자!
String(s[s.index(...)])
’s’ 문자열에서 특정 인덱스로부터 문자열 추출하는 방법.
1. s.index(…) 로 특정 인덱스 생성
2. 이 인덱스 사용해 부분 문자열을 추출
3. 추출된 문자열을 다시 String(…)로 전달해 새로운 문자열 생성
String(s[String.Index(…)])
String.Index 타입 인덱스 사용해 문자열 ‘s’ 일부분 추출하는 방법.
1. String.Index(…)로 문자열 s 일부분 나타내는 인덱스 생성
2. 이 인덱스 사용해 원하는 부분 문자열 추출
3. 추출된 문자열 다시 String(…)로 전달해 새로운 문자열 생성정리하고 보니까 그냥 표현방식만 다르고 똑같은 과정을 거친다는 이야기였다!! 같은 거라고 생각하면 된다 :>
encodedOffset
문자열의 인코딩된 오프셋(offset)을 나타내는 속성이다.
String.Index
를 생성할 때, 문자열 s에서 특정 위치를 나타내는 데 사용되었다.
String.Index(encodedOffset:)
문자열의 인코딩된 오프셋(offset)을 사용하여 인덱스를 생성하는데,
시작점이 아닌 문자열의 실제 위치를 기준으로 중간을 찾아주므로, 홀수 길이의 문자열에서도 중간 문자나 짝수 길이의 문자열에서도 중간 두 문자를 추출할 수 있다.(startIndex, offsetBy를 사용하는 경우에는 시작점을 기준으로 주어진 오프셋까지 이동하도록 한다.)문자열 s의 길이가 홀수일 경우 (s.count - 1) / 2와 s.count / 2가 동일한 인덱스 값을 가리킨다. 따라서 동일한 인덱스 값을 가진 하나의 문자만 추출한다.
문자열 s의 길이가 짝수일 경우 (s.count - 1) / 2와 s.count / 2가 서로 다른 인덱스 값을 가리킨다. 따라서 다른 인덱스 값에 위치한 두 문자를 추출한다.func solution(_ s:String) -> String { return String(s[String.Index(encodedOffset: (s.count - 1) / 2)...String.Index(encodedOffset: s.count / 2)]) } //문자열 s의 길이가 홀수일 경우 "abc" (s.count - 1) / 2 = (3 - 1) / 2 = 1 s.count / 2 = 3 / 2 = 1.5 // 두 값 모두 인덱스 1 가리킨다. // "b" //문자열 s의 길이가 짝수일 경우 "abcd" (s.count - 1) / 2 = (4 - 1) / 2 = 1.5 s.count / 2 = 4 / 2 = 2 // 하나는 인덱스 1을, 하나는 인덱스 2를 가리킨다. // "bc"