Swift 문자열 다루기

이왕 iOS 개발자 되기로 맘 먹은 김에 Swift 공부도 할 겸 해서
이제부터 알고리즘 풀이를 Swift로 해보려고 마음 먹었다 👊👊
import, print와 같은 내장 함수들이 python 과 유사했지만
역시 자료형에 민감한 언어이다 보니 신경써야 할 부분이 많았다
특히 문자열에서 특정 문자에 접근하는 것 골치 아픈 것은 명성이 자자하고
heapq, deque 같은 모듈이 지원이 안되는 경우의 처리가 복잡했다
이제야 보이는 파이썬의 편리함… 그래도 Swift가 훨 빠르다!
그래서 !!! 앞으로 Swift로 알고리즘을 풀 때 나도 참고하고 누군가도 참고하기 위해서 정리해보려고 한다

1. 문자열 입력 받기

readLine()

Swift에서는 문자열을 입력받을 때 readLine() 함수를 사용한다.

  • 현재 행의 끝까지 or EOF(enter)에 도달할 때까지 표준 입력에서 읽은 문자열을 반환
  • String? 형태로 반환 (Optional String)

    Optional : nil값 일수도, 아닐수도 있음
    Nil : 값이 없음 (0이나 “” 빈문자열이 아니고 진짜 없음!을 의미)

let optional_string = readLine()
let string = readLine()!

print()
print(optional_string,type(of : optional_string))
print(string, type(of : string))

image

출력값에서 알 수 있듯이 readLine()으로 불러오면 Optional 값이기 때문에
그냥 문자열처럼 사용하려면 !을 붙여서 Optional을 벗겨줘야한다


응용

  • 정수형 받기
     // Int()함수도 String 값을 Optional Int형태로 변환해주기 때문에 !을 붙여서 Optional을 벗겨준다   
     let N = Int(readLine()!)!
    
  • 띄어쓰기로 구분하여 문자열 받기
    let stringArray = readLine()!.split(separator: " ")
    //입력 : a b c, 출력 : ["a","b","c"]
    
  • 띄어쓰기로 구분하여 정수열 받기
    let intArray = readLine()!.split(separator: " ").map{Int(String($0))!}
    //입력 : 1 2 3, 출력 : [1, 2, 3]
    
  • 띄어쓰기 없이 문자열 받기
    let stringArray2 = Array(readLine()!)
    //입력 : string, 출력 : ["s","t","r","i","n","g"]
    
  • 띄어쓰기 없이 정수열 받기
    let intArray = Array(readLine()!).map{Int(String($0))!}
    //입력 : 12345, 출력 : ["1","2","3","4","5"]
    

2. 특정 문자에 해당하는 index 추출

func firstIndex(of: Character) -> String.Index? : 문자열 내에 해당 Character가 속한 가장 빠른 Index
func lastIndex(of: Character) -> String.Index? : 문자열 내에 해당 Character가 속한 가장 느린 Index
?? : name.firstIndex(of: " ") 의 값이 nil일 경우 name.endIndex를 반환하고, Optional을 벗겨주는 효과

let name = "Marie Curie"
let firstSpace = name.firstIndex(of: " ")
let firstSpace2 = name.firstIndex(of: " ") ?? name.endIndex

print(firstSpace, type(of:firstSpace)) //출력 : Optional(Swift.String.Index(_rawBits: 327943)) Optional<Index>
print(firstSpace2, type(of:firstSpace2)) //출력 : Index(_rawBits: 327943) Index

3. 특정 index에 해당하는 문자 추출

func String.index(Substring.Index, offsetBy: Int) -> Substring.Index

  • String.index(before: /after: ) : 해당 index 직전이나 직후 문자 index 반환
  • String.index(String.startIndex, offsetBy:Int) : startIndex로 부터 Int만큼 떨어진 Character의 Index 반환
let string = "Hello My World"

let fIndex = string.startIndex
let fIndex2 = string.index(after: string.startIndex)
let mIndex = string.index(string.startIndex, offsetBy: string.count/2)
let eIndex = string.index(before: string.endIndex)

print(fIndex, type(of: fIndex))                       //출력 : Index(_rawBits: 15) Index
print(string[fIndex], type (of: string[fIndex]))      //출력 : H Character
print(fIndex2, type(of: fIndex2))                     //출력 : Index(_rawBits: 65799) Index
print(string[fIndex2], type (of: string[fIndex2]))    //출력 : e Character
print(mIndex)                                         //출력 : Index(_rawBits: 459015)
print(string[mIndex])                                 //출력 : y
print(eIndex)                                         //출력 : Index(_rawBits: 852231)
print(string[eIndex])                                 //출력 : d

4. 특정 문자열 구하기 (slicing)

  • String 문자열도 [ ] 를 통하여 특정 Character에 접근하거나 Slicing 할 수 있다
  • 하지만, 배열과는 다르게 [ ] 괄호 안에 Int형이 아닌 Index형을 넣어줘야함 !!!

다음 코드로 String과 Character 배열을 비교해 보았다

var s1 : String = "string"
var s2 :[Character] = ["s","t","r","i","n","g"]

print(s1[0...3]) //String은 정수로 Indexing 할 수 없으므로 컴파일 에러!
print(s1[s1.startIndex...s1.index(before: s1.endIndex)]) //출력 : string
print(s2[0...3]) //출력 : ["s", "t", "r", "i"]
  • String.prefix(Int) : String의 Int만큼의 prefix
  • String.suffix(Int) : String의 Int만큼의 suffix
 let greet = "안녕하세요 !"
 let short talk = greet.prefix(2)
 print(short talk) //출력 : 안녕

let Joke = "어쩔티비"
let tv = Joke.suffix(2)
print(tv) //출력 : 티비

한동안은 문자열 사용할 때 구글링 할 일 없을 것 같다 :)
swift로 알고리즘 푸는 사람들이 더욱 많아졌음 좋겠다
이제 백준도 많이 풀어봐야지 ~!!🤩