cchanmi
[Swift] String index에 접근해 보자 (Feat: Substring) 본문
swift로 알고리즘 문제를 풀다 보면 string의 index에 접근해야 할 상황이 종종 있습니다.
swift는 다른 언어들처럼 index를 정수로 받지 않아서 조금 까다롭더라구요.
let hello = "hello"
let first = hello[0] // error
그래서 우리는 swift에서는 string의 index를 가리키기 위해서는 String.index라는 타입을 이용해야 합니다.
String.index란?
공식 문서에 따르면 문자열에서 문자 또는 코드 단위의 위치라고 정의되어 있습니다.
첫번째 index를 가리키는 법
그럼 String.index를 사용하여서 0번째 인덱스를 가리키려면 어떻게 해야 할까요?
let first = string[string.startIndex] // h
startIndex를 사용하면 됩니다!
여기 있는 string은 우리가 사용할 string 타입의 변수 또는 배열을 넣어 주면 됩니다.
아래는 예시입니다.
let first = hello[hello.startIndex] // h
난 그것도 모르고 string 그대로 붙여 놓고 왜 error 나는지 한참을 헤맨… ㅋ 바보
마지막 index를 가리키는 법
endIndex에 접근하면 됩니다.
let first = string[string.endIndex] // error
그런데 endIndex에 그대로 접근하게 되면 프로그램이 죽게 됩니다.
endIndex의 경우는 우리가 생각하는 마지막 문자를 가리키는 것이 아니라, 그 다음의 정~~말 아무것도 없는 끝 부분을 가리킨다고 합니다!
마치 C String의 문자열 마지막을 장식하는 ‘\0’의 위치를 의미한다고 보면 된다고들 많이들 예시를 들어주셨더라구요!
그러면 endIndex를 어떻게 사용해야 하느냐… 고민이 된다면 좀 더 유동적으로 인덱스를 가리킬 수 있는 다른 메서드들이 있습니다. 무엇이 있는지 또 알아볼까요???
after, before
let secondIndex = string.index(after: string.startIndex)
let second = string[secondIndex] // "e"
index(after:) 메서드를 사용하여 0번째 인덱스가 아닌 그 다음 인덱스에 접근할 수 있습니다. hello → e
(0번째 인덱스 + 1)로 생각하면 되겠네요!
그렇다면 index(before:) 메서드도 사용해 봅시다!
let endIndex = string.index(before: string.endIndex)
let end = string[endIndex] // "o"
index(before:) 메서드는 설명 안 해도 이제 알겠죠???
기존의 endIndex는 마지막 문자를 가리키는 것이 아닌, 문자열 끝 그 자체를 가리켰습니다!
그런데 우리는 마지막 문자의 인덱스가 필요하다면??? 이 메서드를 사용하여 구할 수 있습니다!
(문자열 끝 그 자체 - 1) = 마지막 문자 라고 생각할 수 있겠네요!
hello → o
그렇다면 이제 n번째 인덱스의 문자를 구하는 방법을 알아봅시다 ㅎㅎ … ….
n번째 index 가리키는 법
다행히도 관련된 좋은 메서드가 존재하네요 ~
let thirdIndex = string.index(string.startIndex, offsetBy: 2) // "l"
index의 시작값이 0이기 때문에 0, 1, 2 → 3번째 index에 접근할 수 있습니다.
string.startIndex 파라미터는 기준이 되는 시작 위치를 말하고 있는 것 같네요!
hello 문자열로 생각해 보면 h가 string.startIndex이고, 3번째 index인 l을 가리키는 걸 알 수 있습니다!
참고로 offsetBy의 파라미터는 음수도 가능하다고 하네요.
문자열에서 index 값 구하기
문자열에서 특정 문자를 검색하여 index 값을 구하는 방법도 있습니다.
let index = string.index(of: "찾고자 하는 문자"
index(of:) 메서드를 사용하면 찾고자 하는 문자의 위치를 가리키는 String.index 값을 구할 수 있습니다.
알고리즘 문제를 풀다 보면 가끔 SubStrng이라는 타입이 보이게 되는데 … … 항상 뭔지 모르고 넘어갔다가 이번 기회에 정리해 보겠습니다 ㅎㅎ
SubString이란?
SubString이란 말 그대로 String의 일부를 뜻합니다!
이름처럼 특정 문자열의 부분 문자열을 담기 위한 특수한 타입입니다. 하지만 정확하게 String 타입이 아니기 때문에 String 타입을 필요로 하는 곳에 사용할 수가 없습니다. 물론, 문자열로 바꾸는 건 어렵지 않아요!
그러면 왜 SubString과 String을 나눠 놓았을까… …
둘의 차이점이 뭘까 알아보니,
subString은 새로운 메모리를 할당하지 않고, 기존 String의 메모리를 재사용한다는 점에서 메모리 할당 비용을 줄여 준다는 장점을 가지고 있다고 하네요!
하지만 그것과 별개로 장기적으로 String을 재사용하는 경우에는 적절하지 않은 방법이기 때문에 새로운 String을 만드는 것을 권장한다고 합니다. ㅠㅠ (왜…? 아는 사람 코멘트 달아주세요,,)
SubString 그래서 너 언제 사용하냐……?
우리가 위에서 방금 공부한 String.index에 범위를 만들어 구하게 될 때, subString을 반환하게 됩니다.
우리가 꼭 하나의 문자의 index만 구할 것이 아니기 때문에 이부분도 꼭 알아두도록 합시다!
let start = string.index(after: string.startIndex)
let end = string.index(before: string.endIndex)
let result = string[start...end] // "ello"
String.index를 사용하여 start부터 end까지의 범위를 만들었으며, 이것을 문자열의 subscript를 이용하면 부분문자열(Substring)로 값이 담기게 됩니다.
result 변수의 값은 SubString 타입이고, 이 SubString은 새로운 메모리를 할당하고 있지 않고 재사용한다고 했잖아요???
그래서 result 변수는 새로운 메모리를 할당하지 않고, “hello” 문자열을 담고 있는 기존의 hello 변수의 메모리를 재사용합니다. 그러면서 “ello”를 가리키고 있겠네요!
출처
https://hcn1519.github.io/articles/2017-07/swift_Str
'Swift' 카테고리의 다른 글
[Swift] Dictionary에서 value를 이용해 key 구하기 (0) | 2023.05.18 |
---|---|
[Swift] Dictionary, Set 들어온 순서대로 값 출력하기 (0) | 2023.05.13 |
[Swift] String.index에 접근해 보자 (2) (Feat: prefix, suffix) (0) | 2023.03.04 |
[Swift] 문자열의 문자 재정렬 (reversed, sort, sorted) (0) | 2022.09.06 |