728x90
조건 split
let str = "abd124kbksbjb62".split { !$0.isNumber }
print(str) // ["124", "62"]
dict 필터
let s = [1, 2, 2, 3, 3, 3, 4, 4, 4]
let dict = Dictionary(grouping: Array(s).map(String.init), by: { $0 }).filter { $0.value.count > 1 }
print(dict) // ["3": ["3", "3", "3"], "2": ["2", "2"], "4": ["4", "4", "4"]]
여러 조건 split
let str = "nabcvcvacbacac".split { $0 == "a" || $0 == "b" || $0 == "c" }.map { String($0) }
print(str) // ["n", "v", "v"]
문자열 range
import Foundation
let str = "12afabsaoabctgi0abcsdg"
let pat = "abc"
if let range = str.range(of: pat) {
print(String(str.prefix(upTo: range.upperBound))) // 12afabsaoabc
}
if let range = str.range(of: pat, options: .backwards) {
print(String(str.prefix(upTo: range.upperBound))) // 12afabsaoabctgi0abc
}
문자열 → 배열, 배열 교체
let str = "123456789"
let (s, e) = (1, 5)
var my_string = Array(str)
my_string.replaceSubrange(s...e, with: Array(my_string[s...e].reversed()))
print(my_string) // ["1", "6", "5", "4", "3", "2", "7", "8", "9"]
범위 패턴 매칭
let month = "05"
let notMonth = "13"
print(("01"..."12") ~= month) // true
print(("01"..."12") ~= notMonth) // false
contains 정규식
let number = "212312"
let notNumber = "3y3235"
extension String {
var isSixDigitNumber: Bool {
let digits = /[0-9]{6}/
return self.contains(digits) && self.count == 6 ? true : false
}
}
print(number.isSixDigitNumber) // true
print(notNumber.isSixDigitNumber) // false
dict key, value 반환
let airports = ["LHR": "London Heathrow", "YYZ": "Toronto Pearson"]
let airportCodes = [String](airports.keys)
let airportNames = [String](airports.values)
print(airports) // ["LHR": "London Heathrow", "YYZ": "Toronto Pearson"]
print(airportCodes) // ["LHR", "YYZ"]
print(airportNames) // ["London Heathrow", "Toronto Pearson"]
범위 slicing
let str = ["123", "234", "345", "456"]
let (s, l) = (1, 2)
let slicing = str.map {
let slice = Int($0.prefix(s + l).suffix(l))!
print($0, "->", slice, terminator: ", ")
return slice
}.filter {
$0 % 2 == 0
}
print() // 123 -> 23, 234 -> 34, 345 -> 45, 456 -> 56,
print(slicing) // [34, 56]
시퀀스
var n = 1
let number = sequence(first: 0) { i in i + 1 == n ? nil : i + 1 }.map { $0 }
print(number) // [0]
n = 10
let number2 = sequence(first: 0) { i in i + 1 == n ? nil : i + 1 }.map { $0 }
print(number2) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
배열 범위 초기화
let (start, end) = (10, 20)
let arr = [Int](start...end)
print(arr) // [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
포함 검색
let str = "012512"
let str2 = "0550505050"
let s = Set(String(str)).isSubset(of: ["0", "5"])
let s2 = Set(String(str2)).isSubset(of: ["0", "5"])
print(s) // false
print(s2) // true
소수 알고리즘
import Foundation
func isPrime(_ num: Int) -> Bool {
if num == 1 { return false }
else {
var i = 2
while i <= Int(sqrt(Double(num))) {
if num % i == 0 { return false }
i += 1
}
return true
}
}
삼항 연산자 대체
func solution1(_ price:Int, _ money:Int, _ count:Int) -> Int64 {
var totalPrice = -(1...count).reduce(into: Int64(money), { $0 -= Int64($1 * price) })
return totalPrice > 0 ? totalPrice : 0
}
// 삼항 연산자 -> max
func solution2(_ price:Int, _ money:Int, _ count:Int) -> Int{
return max((count + 1) * count / 2 * price - money , 0)
}
파운데이션 임포트 시간 차이
// import Foundation
let input = Int(readLine()!)!
var stocks = [(Int, Int)]()
for i in 1...input {
let stock = readLine()!.split(separator: " ").map({ Double(String($0))! })
stocks.append((Int(stock[0] * stock[1] * 10.0), i))
}
for stock in stocks.sorted(by: { ($0.0, $1.1) > ($1.0, $0.1) }) {
print(stock.1, terminator: " ")
}
import Foundation
// import Foundation
여러 조건 정렬, 튜플 정렬
let arr = [(1, 2), (2, 1), (1, 1), (6, 9)]
let sorted = arr.sorted { ($0.0, $1.1) < ($1.0, $0.1) }
print(sorted) // [(1, 2), (1, 1), (2, 1), (6, 9)]
typealias
typealias person = (weight: Int, height: Int)
let N = Int(readLine()!)!
var people = [person]()
for _ in 0..<N {
let input = readLine()!.split(separator: " ").map{Int(String($0))!}
people.append((input[0],input[1]))
}
for p in people {
let condition = people.filter { p.weight < $0.weight && p.height < $0.height}
print(condition.count+1, terminator: " ")
}
스택 방향
// 진행 방향: 왼쪽 -> 오른쪽
let stack = ["1", "2", "3"]
// 진행 방향: 오른쪽 -> 왼쪽
let reversed = stack.reversed()
입출력 개선
import Foundation
let file = FileIO()
print(file.readInt()) // 5 입력 -> 5
final class FileIO {
private let buffer:[UInt8]
private var index: Int = 0
init(fileHandle: FileHandle = FileHandle.standardInput) {
buffer = Array(try! fileHandle.readToEnd()!) + [UInt8(0)]
}
@inline(__always) private func read() -> UInt8 {
defer { index += 1 }
return buffer[index]
}
@inline(__always) func readInt() -> Int {
var sum = 0
var now = read()
var isPositive = true
while now == 10 || now == 32 { now = read() }
if now == 45 { isPositive.toggle(); now = read() }
while now >= 48, now <= 57 {
sum = sum * 10 + Int(now - 48)
now = read()
}
return sum * (isPositive ? 1:-1)
}
@inline(__always) func readString() -> String {
var now = read()
while now == 10 || now == 32 { now = read() }
let beginIndex = index - 1
while now != 10, now != 32, now != 0 { now = read() }
return String(bytes: Array(buffer[beginIndex..<(index-1)]), encoding: .ascii)!
}
@inline(__always) func readByteSequenceWithoutSpaceAndLineFeed() -> [UInt8] {
var now = read()
while now == 10 || now == 32 { now = read() }
let beginIndex = index - 1
while now != 10, now != 32, now != 0 { now = read() }
return Array(buffer[beginIndex..<(index-1)])
}
}
stride reduce
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let str = stride(from: 10, to: 5, by: -1).reduce("", { $0 + String(arr[$1]) })
print(str) // 109876
n진수 -> 10진수, 10진수 -> n진수 변환
print(String(19, radix: 3))
// 19(10) -> 201(3)
print(Int("201", radix: 3)!)
// 201(3) -> 19(10)
A to Z 인덱스 dict
var dict = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".enumerated().reduce(into: [:]) {
$0[$1.element] = $1.offset + 1
}
print(dict)
/*
["W": 23, "U": 21, "B": 2, "X": 24, "A": 1, "N": 14, "P": 16, "H": 8, "G": 7, "J": 10, "Y": 25, "F": 6, "K": 11, "S": 19, "D": 4, "O": 15, "T": 20, "C": 3, "Q": 17, "R": 18, "I": 9, "M": 13, "V": 22, "Z": 26, "E": 5, "L": 12]
*/
computed property
var isAlphabetic: Bool {
return self.ascii.filter{ 97...122 ~= $0 }.count == 2
}
원소 반복 초기화
var visited = [Bool](repeating: false, count: dungeons.count)
범위 찾기 components
let answer = s.components(separatedBy: ["{","}"])
빈 값없는 split
var b = s.split(separator: "{", omittingEmptySubsequences: true)
reduce 타입 캐스팅 초기화
// 1
split.reduce(into: Array<Int>())
// 2
.reduce(([], 0)) { (tuple, day) -> ([Int], Int) in ... }
문자형 숫자를 이어 붙였을 때 큰 수 정렬
let numbers = ["0", "1", "2", "3", "4", "5", "6", "7"]
print(numbers.sorted(by: { ($0 + $1) >= ($1 + $0) })) // ["7", "6", "5", "4", "3", "2", "1", "0"]
우선순위 힙 구현(0-indexed)
struct PriorityQueue<T: Comparable> {
private var heap: [T] = []
private let compare: (T, T) -> Bool
init(_ sort: @escaping (T, T) -> Bool) { self.compare = sort }
var isEmpty: Bool { heap.isEmpty }
var count: Int { heap.count }
var top: T? { heap.first }
mutating func push(_ value: T) {
heap.append(value)
var i = heap.count - 1
while i > 0, compare(heap[i], heap[(i - 1) / 2]) {
heap.swapAt(i, (i - 1) / 2)
i = (i - 1) / 2
}
}
mutating func pop() -> T? {
guard !heap.isEmpty else { return nil }
if heap.count == 1 { return heap.removeFirst() }
heap.swapAt(0, heap.count - 1)
var i = 0
let popped = heap.removeLast()
while true {
let (left, right) = (i * 2 + 1, i * 2 + 2)
var next = i
if left < heap.count, compare(heap[left], heap[next]) { next = left }
if right < heap.count, compare(heap[right], heap[next]) { next = right }
if next == i { break }
heap.swapAt(i, next)
i = next
}
return popped
}
}
set 중복 검사
Set(["1", "2", "2", "3"]) == ["0"]
dict 초기화
let year = [2000, 2001, 2002, 2003, 2004, 2005]
let dict: [Int: Int] = Dictionary(uniqueKeysWithValues: zip(year, (0..<year.count)))
print(dict) // [2003: 3, 2000: 0, 2001: 1, 2002: 2, 2004: 4, 2005: 5]
let sizes = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
let dict2 = Dictionary(grouping: sizes) { $0 }
print(dict2) // [1: [1], 3: [3, 3, 3], 2: [2, 2], 4: [4, 4, 4, 4]]
2차원 배열 순회
photo.map { $0.reduce(0) { $0 + (score[$1] ?? 0) } }
O(1) Remove First
// removeFirst는 O(n)이라서 reversed -> removeLast
goal.forEach { card in
if let card1 = cards1.first, card1 == card {
cards1.removeFirst()
cards.append(card1)
}
if let card2 = cards2.first, card2 == card {
cards2.removeFirst()
cards.append(card2)
}
}
!Contains
let filtered = "abcdefghijklmnopqrstuvwxyz".filter { !skip.contains($0) }.map { $0 }
// "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
reduce에 딕셔너리 사용
// 1
var s = tangerine.reduce(into: [:]) { partialResult, size in
partialResult[size, default: 0] += 1
}
.reduce((0, 0)).0
// 2
let maps = filtered.enumerated().reduce(into: [:]) { dict, v in
dict[v.element] = filtered[(v.offset+index) % filtered.count]
}
문자열 연결(join)
s.map { String(maps[$0]!) }.joined()
정규 표현식 문자열 검사
// 정규 표현식
new_id = new_id.replacingOccurrences(of: "[^a-z0-9-_.]", with: "", options: .regularExpression)
new_id = new_id.replacingOccurrences(of: "(\\.)\\1+", with: ".", options: .regularExpression)
new_id = new_id.replacingOccurrences(of: "^\\.", with: "", options: .regularExpression).replacingOccurrences(of: "\\.$", with: "", options: .regularExpression)
배열 마지막 n개 원소 출력
// suffix(n): stack이 n개 이하여도 가능
if stack.suffix(4).map({ String($0) }).joined() == "1231" {
stack.removeLast(4)
return $0 + 1
}
2차원 배열 popLast
// popLast를 위해서 배열 rotate
var stacks: [[Int]] = Array(repeating: [], count: board.count)
board.reversed().forEach {
$0.enumerated().forEach {
if $0.1 != 0 {
stacks[$0.0].append($0.1)
}
}
}
// [[0, 0, 0, 0, 0], [0, 0, 1, 0, 3], [0, 2, 5, 0, 1], [4, 2, 4, 4, 2], [3, 5, 1, 3, 1]]
// -90 -> [[3, 4], [5, 2, 2], [1, 4, 5, 1], [3, 4], [1, 2, 1, 3]]
[[1, 2, 3], [2, 2, 3], [3, 3, 3]] 배열 생성
func solution(_ n:Int, _ left:Int64, _ right:Int64) -> [Int] {
(left...right).map {
Int(max(Int64($0) / Int64(n) + 1, Int64($0) % Int64(n) + 1))
}
}
728x90
'Algorithm' 카테고리의 다른 글
파이썬 알고리즘 문법 (0) | 2025.03.30 |
---|---|
SwiftUI: [1차] 뉴스 클러스터링 (0) | 2024.04.04 |
SwiftUI: [1차] 캐시 (0) | 2024.04.03 |
SwiftUI: 의상 (0) | 2024.04.02 |
SwiftUI: H-Index (0) | 2024.04.02 |