✏️ 알고리즘 문제 풀이에서 자주 쓰는 Swift 문법, 메서드, 함수 정리등 정리하겠습니다.
[입/출력 처리]
키보드 값 입력받기
let input = readLine() // return 값은 Optional String 형식
let input = readLine()! // return 값은 String 형식
// Int 값 입력받기
let input = Int(readLine()!)!
키보드 입력받은 값 공백으로 구분하기
- split() 으로 구분 (예시: 1 2 3 4)
var nums = readLine()!.split(separator: " ") // ["1", "2", "3", "4"]
- components() 로 구분 (예시: 1 2 3 4)
var nums = readLine()!.components(separatedBy: " ") // ["1", "2", "3", "4"]
N개의 줄만큼 입력받기
let line = Int(readLine()!)!
var result: [Int] = []
for _ in 0..<line { result.append(Int(readLine()!)!) }
print(result)
// 입력
// 4 (n개의 줄)
// 5
// 7
// 2
// 9
// 출력
// [5, 7, 2, 9]
print(_:separator:terminator:)
- separator: 각 항목 사이에 출력할 문자열. 기본값은 공백(" ")
- terminator: 모든 항목이 출력된 후 출력될 문자열. 기본값은 줄바꿈("\n")
// separator 사용 예시 (공백대신 -을 넣어줌)
print(1, 2, 3, 4, separator: "-") // 1-2-3-4
// terminator 사용 예시 (줄 바꿈 대신 ...을 넣어줌)
print("Loading", terminator: "...")
print("Done!")
// Loading...Done!
[배열]
오름차순/내림차순 정렬
- 기본으로는
sort(by: <)
의 형태이다. sort(by: <)
는 오름차순 정렬이며, Swift의 기본 정렬 기준이 오름차순(<)이기 때문에sort()
로 생략하여 사용이 가능하다.sort(by: >)
는 내림차순 정렬이며, 기본 정렬 기준이 아니기 때문에 ()안에by: >
를 반드시 명시해야한다.
// sort() 예시
var a = [5, 1, 4, 2, 3]
a.sort()
print(a) // [1, 2, 3, 4, 5] - 생략된 오름차순
a.sort(by: <)
print(a) // [1, 2, 3, 4, 5] - 명시된 오름차순
a.sort(by: >)
print(a) // [5, 4, 3, 2, 1] - 명시된 내림차순 (생략 불가)
// sorted() 예시
var b = [5, 1, 4, 2, 3]
let sortedArr = b.sorted() // 생략된 오름차순 복사본
print(sortedArr) // [1, 2, 3, 4, 5]
let sortedArr = b.sorted(by: <) // 명시된 오름차순 복사본
print(sortedArr) // [1, 2, 3, 4, 5]
let sortedArr = b.sorted(by: >) // 명시된 내림차순 복사본 (생략 불가)
print(sortedArr) // [5, 4, 3, 2, 1]
배열 뒤집기
reverse()
,reversed()
를 사용하여 배열을 뒤집는다.reverse()
는 반환값이 없고, 원본 배열을 직접 뒤집는다.- 원본 배열을 변경하지 않고 복사본을 반환하려면
reversed()
를 사용하면 된다.
// reverse() 예시
var arr = [1, 2, 3, 4]
arr.reverse()
print(arr) // [4, 3, 2, 1]
// reverse()는 반환값이 없기에, let result = arr.reverse()를 작성하게 되면
// print(result)로 출력하면 결과로 Void 값인 ()만 출력된다.
// reversed() 예시
let arr = [1, 2, 3, 4]
let reversedArr = arr.reversed()
print(Array(reversedArr)) // [4, 3, 2, 1]
- reversed()는
ReversedCollection<Array<Element>>
타입을 반환함 - 그렇기에 보통 Array()로 감싸 배열로 변환해서 사용한다.
joined() 메서드를 사용한 값 합치기
- joined() 메서드는 배열 안의 시퀀스(문자열, 배열 등)를 하나로 이어 붙인다.
let words = ["Hello", "World"]
let result = words.joined()
print(result) // HelloWorld
// separator(구분자)를 지정하면 원하는 문자열로 연결할 수 있다.
let words = ["Hello", "World"]
let result = words.joined(separator: "-")
print(result) // Hello-World
// 2차원 배열을 1차원 배열로 펼치기
let numbers = [[1, 2], [3, 4], [5, 6]]
let flattened = numbers.joined()
print(Array(flattened)) // [1, 2, 3, 4, 5, 6]
문자열 배열의 모든 원소를 순서대로 이어붙인 결과를 반환하는 코드 (프로그래머스 문제 예시)
func solution(_ arr:[String]) -> String {
return arr.joined()
}
print(solution(["a", "b", "c"]))
// 출력 : abc
[수학]
절대값 변환
abs(-31) // 31
abs(31) // 31
max(), min()
- max(): 전달인자 중 가장 큰 값을 옵셔널로 반환한다.
- min(): 전달인자 중 가장 작은 값을 옵셔널로 반환한다.
- max(_:_:), min(_:_:)는 두 값을 비교할 때 사용하는 함수이며, 반환값은 옵셔널이 아니다.
- max(), min()에 대해 정리한 글
let heights = [67.5, 65.7, 64.3, 61.1, 58.5, 60.3, 64.9]
let greatestHeight = heights.max()!
print(greatestHeight) // 67.5
let smallestHeight = heights.min()!
print(smallestHeight) // 58.5
// 두 값을 비교할때 사용 max(_:_:), min(_:_:)
let a = 100
let b = 20
let bigger = max(a, b)
print("더 큰 값은:", bigger) // 더 큰 값은: 100
let smaller = min(a, b)
print("더 작은 값은:", smaller) // 더 작은 값은: 20
제곱 계산하기 (pow)
- pow(_:_:)는 Double 타입 인자를 받으며, 반환값도 Double이다.
- Foundation 프레임워크에 정의되어 있는 함수이므로, 사용하려면 import Foundation이 필요하다
- Int 타입에는 직접 사용할 수 없으며, 필요하다면 Double로 형 변환해야 한다.
- Float 타입을 사용하고 싶다면, powf(_:_:)를 사용해야 한다.
import Foundation
var number: Double = 2.0
print(pow(number, 3)) // 8.0 -> (2의 3제곱)
배수인지 확인하는 메서드 isMultiple(of: )
- 해당 값이 주어진 수의 배수인지 여부를 Bool로 반환한다.
let number = 10
if number.isMultiple(of: 2) {
print("\(number) is a multiple of 2")
}
- isMultiple(of: ) 메서드로 짝수와 홀수를 구분할 수 있다.
// 짝수인지 확인
number.isMultiple(of: 2) // true
// 홀수인지 확인(느낌표)
!number.isMultiple(of: 2) // true
stride()
- stride()는 숫자 범위를 일정한 간격으로 순회할 수 있도록 도와주는 함수이다.
stride(from:to:by:)
와stride(from:through:by:)
두 가지 형태가 있다.from
(시작 값)부터to
(도착 전 값) 또는through
(도착 값)까지by
(증가 또는 감소 간격)만큼 진행한다.to
는 끝 값을 포함하지 않으며,through
는 끝 값을 포함한다.
for문과 stride 함수 같이 사용
let input = Int(readLine()!)!
// stride(from:to:by:) -> 0은 포함되지 않음
for i in stride(from: input, to: 0, by: -1) {
print(i, terminator: " ")
}
// 입력: 5 -> 출력: 5 4 3 2 1
// stride(from:through:by:) -> 0까지 포함
for i in stride(from: input, through: 0, by: -1) {
print(i, terminator: " ")
}
// 입력: 5 -> 출력: 5 4 3 2 1 0
위 아래의 차이는, to이냐 through이냐의 차이점이다. 자세한 내용을 알고 싶다면, stride 함수를 보면 좋을 것 같다.
[반복문]
forEach
- forEach는 배열 등 컬렉션의 각 요소에 대해 순차적으로 작업을 수행할 때 사용한다.
- 클로저 내에서 각각의 요소를 가져와 사용이 가능하다.
- 단순한 출력이나 조건 작업 등을 수행할 때 주로 사용하며, return, break, continue를 사용할 수 없다.
let numbers = [1, 2, 3, 4, 5]
numbers.forEach { number in
print("현재 숫자는 \(number)입니다.")
}
// 출력:
// 현재 숫자는 1입니다.
// 현재 숫자는 2입니다.
// 현재 숫자는 3입니다.
// 현재 숫자는 4입니다.
// 현재 숫자는 5입니다.
enumerated()
- 배열 등 컬렉션을 반복할 때, 인덱스와 값을 동시에 사용할 수 있게 해주는 메서드이다.
- 튜플 형태로 (index, element)를 반환한다.
let fruits = ["apple", "banana", "lemon"]
for (index, fruit) in fruits.enumerated() {
print("\(index)번째 과일은 \(fruit)입니다.")
}
// 출력
// 0번째 과일은 apple입니다.
// 1번째 과일은 banana입니다.
// 2번째 과일은 lemon입니다.
[고차함수]
map (각 요소를 변형하기)
let numbers = [1, 2, 3, 4, 5]
let squared = numbers.map { $0 * $0 }
print(squared) // [1, 4, 9, 16, 25]
filter (조건에 맞는 요소만 걸러내기)
let numbers = [1, 2, 3, 4, 5]
let even = numbers.filter { $0 % 2 == 0 }
print(even) // [2, 4]
- 반드시 Bool을 반환함 (true면 포함, false면 제외)
reduce (값을 하나로 합치기)
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 15
// 아래와 같이 축약도 가능 (동일하게 작동)
// let sum = numbers.reduce(0, +)
- reduce(0) -> 초기값은 0 (누적을 0부터 시작함)
- { $0 + $1 } -> 클로저
- $0은 지금까지 누적된 값
- $1은 배열에서 현재 처리중인 요소
[문자열]
asciiValue
- asciiValue는 Character 타입의 문자가 ASCII 문자일 경우, 해당 아스키 코드 값을 UInt8? 타입으로 반환한다. 불가능한 경우에는 nil 을 반환한다.
let character: Character = "A"
print(character.asciiValue!) // 65
isLowercase / isUppercase (문자의 대소문자 여부 확인)
- 각각 문자가 소문자 또는 대문자인지 확인할 수 있는 프로퍼티이다.
isLowercase
: 소문자인지 확인하는 프로퍼티. 소문자라면 true, 아니면 falseisUppercase
: 대문자인지 확인하는 프로퍼티. 대문자라면 true, 아니면 falseCharacter
타입에만 사용 가능하며, 문자 하나에만 적용된다.
let x: Character = "x"
let y: Character = "Y"
print(x.isLowercase) // true
print(x.isUppercase) // false
print(y.isLowercase) // false
print(y.isUppercase) // true
lowercased() / uppercased() (문자열의 대소문자 변환)
- 문자열 전체를 소문자 또는 대문자로 변환한 문자열을 반환한다.
- 원본 문자열은 변하지 않고, 변환된 결과를 새로 리턴한다.
let americano = "AmerICaNo"
print(americano.lowercased()) // "americano" (소문자로 변환)
print(americano.uppercased()) // "AMERICANO" (대문자로 변환)