본문 바로가기

iOS/Swift

[Swift] Cording_Test 준비

추가 예정

 

기본 입력 받기

// return String
var input = readLine()!

// return Int
var input = Int(readLine()!)!

 

개행없는 print

print("singyuKangHello", terminator:"")

 

공백 있는 String 받기

ex) "a b c d e"

var my_string = readLine()!.split(separator : " ") //return [SubString]

var my_string = readLine()!.split(separator : " ") //return [String]

// FileIO, 입력받으면서 리스트에 바로 추가하기
array.append((file.readInt(), file.readInt()))

 

문자열에 특정 문자 바꾸기

 

let str = "sinGyu!Kang!"
let str2 = str.replacingOccurrences(of: "!", with: "?")
print(str2) // sinGyu?Kang?

 

forEach

//배열이나 String 각각 수행을 원할때

 

let nums: [Int] = [1, 2, 3, 4]

nums.forEach {
	print($0) // 1 2 3 4
}

 

배열 요소 추가

 

var array:[Int] = [1,2]
array.append(3)
array.append(contentOf: [4,5,6,7]) // [1,2,3,4,5,6,7]

 

1차원 배열

let arr = [Int]() 

let arr = Array(repeating: 0, count: 5)  //[1,2,3,4,5]
let arr = [Int](repeating: 0, count: 5)

 

2차원 배열

let arr = [[Int]]() 

let arr = Array(repeating: Array(repeating: 0, count: 3), count: 5) 
let arr = [[Int]](repeating: [Int](repeating: 0, count: 3), count: 5)

 

map

var my_string = ["1","2","3"]

my_string.map{ Int($0)! }  // 배열 하나하나 접근하여 원하는 값으로 반환

filter

var array = [1,2,3,4]

array.filter { $0 % 3 == 0 }   // [3] 반환

 

reduce

let numbers:[Int] = [1,2,3,4,5]

var sum = numbers.reduce(0){(result, element) in return result + element}

var sum = numbers.reduce(0, +)

 

contains

 

var numbers:[Int] = [1,2,3,4,5]

var isNumber_1 = numbers.contains(1) //true
var isNumber_6 = numbers.contains(6) //false

 

 

 

remove

var nums : [Int] = Array(1...4)
nums.remove(at: 0)
// index 조회후 제거

 

 

 

순열과 조합 SWIFT 구현

func permutation<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    var visited = Array(repeating: false, count: array.count)
    
    func cycle(_ now: [T]) {
        if now.count == n {
            result.append(now)
            return
        }
        
        for i in 0..<array.count {
            if visited[i] {
                continue
            } else {
                visited[i] = true
                cycle(now + [array[i]])
                visited[i] = false
            }
        }
    }
    
    cycle([])
    
    return result
}

func combination<T: Comparable>(_ array: [T], _ n: Int) -> [[T]] {
    var result = [[T]]()
    if array.count < n { return result }

    var stack = array.enumerated().map { ([$0.element], $0.offset) }
    
    while stack.count > 0 {
        // print(stack)
        let now = stack.removeLast()
        
        let elements = now.0
        let index = now.1
        
        if elements.count == n {
            result.append(elements.sorted())
            continue
        }
        
        guard index+1 <= array.count-1 else { continue }
        
        for i in index+1...array.count-1 {
            stack.append((elements + [array[i]], i))
        }
        
    }
    
    return result
}

 

 

 

class Queue{
    var enqueue: [Int]
    var dequeue: [Int] = []
    
    var isEmpty: Bool{
        return enqueue.isEmpty && dequeue.isEmpty
    }
    var count: Int{
        return enqueue.count + dequeue.count
    }
    
    init(_ queue:[Int]){
        self.enqueue = queue
    }
    
    func push(_ n: Int){
        enqueue.append(n)
    }
    
    func pop() -> Int?{
        if dequeue.isEmpty{
            dequeue = enqueue.reversed()
            enqueue.removeAll()
        }
        return dequeue.popLast()
    }
    
}

// Array 로 구현한 Queue
struct ArrayQueue<T> {
    // 빈 Array 선언
    private var queue: [T] = []

    // Queue 내 원소 개수
    public var count: Int {
        return queue.count
    }

    // Queue 가 비었는지
    public var isEmpty: Bool {
        return queue.isEmpty
    }

    // 삽입 메소드
    public mutating func enqueue(_ element: T) {
        queue.append(element)
    }

    // 삭제 메소드
    public mutating func dequeue() -> T? {
        return isEmpty ? nil : queue.removeFirst()
    }

    // Queue 전체 삭제
    public mutating func clear() {
        queue.removeAll()
    }
}

 

 

파일 입출력으로 입력받기

// 라이노님의 FileIO
final class FileIO {
    private var buffer:[UInt8]
    private var index: Int

    init(fileHandle: FileHandle = FileHandle.standardInput) {
        buffer = Array(fileHandle.readDataToEndOfFile())+[UInt8(0)] // 인덱스 범위 넘어가는 것 방지
        index = 0
    }

    @inline(__always) private func read() -> UInt8 {
        defer { index += 1 }

        return buffer.withUnsafeBufferPointer { $0[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 str = ""
        var now = read()

        while now == 10
                || now == 32 { now = read() } // 공백과 줄바꿈 무시

        while now != 10
                && now != 32 && now != 0 {
            str += String(bytes: [now], encoding: .ascii)!
            now = read()
        }

        return str
    }
}

let file = FileIO()

 

let N = file.readInt()
let T = file.readString()

 

최소 힙

// 최소 힙 구현
struct Heap <T: Comparable> {
    var heap = [T]()

    private func getParent(_ index: Int) -> T {
        heap[index / 2]
    }

    private func getLeftChild(_ index: Int) -> T {
        heap[index * 2]
    }

    private func getRightChild(_ index: Int) -> T {
        heap[index * 2 + 1]
    }

    func isEmpty() -> Bool {
        heap.count <= 1
    }

    mutating func push(_ data: T) {
        if isEmpty() { heap.append(data) }
        var index = heap.count
        heap.append(data)

        while index > 1 {
            let parent = getParent(index)
            guard parent > data else { break }
            heap[index] = parent
            index /= 2
        }
        heap[index] = data
    }

    mutating func pop() -> T? {
        guard !isEmpty() else { return nil }
        let item = heap[1]
        let data = heap.removeLast()
        let size = heap.count - 1

        guard !isEmpty() else { return item }
        var (parent, child) = (1, 2)
        while child <= size {
            if child < size && getLeftChild(parent) > getRightChild(parent) {
                child += 1
            }
            guard data > heap[child] else { break }
            heap[parent] = heap[child]
            parent = child
            child *= 2
        }
        heap[parent] = data
        return item
    }
}

 

이진탐색 구현

// 반복문으로 구현하기
func binarySearch(_ array: [Int], num: Int) -> Bool {
    var start = 0
    var end = (array.count - 1)
    
    while start <= end {
        let mid = (start + end) / 2
        
        if array[mid] == num { return true }
        if array[mid] > num {
            end = mid - 1
        } else {
            start = mid + 1
        }
    }
    return false
}

 

우선순위 큐 구현

 

public struct Heap<T> {
    
    private var nodes = [T]()
    
    private var orderCriteria: (T, T) -> Bool
    
    public init(sort: @escaping (T, T) -> Bool) {
        // 최대 힙인지 최소 힙인지 기준을 잡는다.
        self.orderCriteria = sort
    }
    
    public init(array: [T], sort: @escaping (T, T) -> Bool) {
        self.orderCriteria = sort
        configureHeap(from: array)
    }
    
    public var isEmpty: Bool {
        return count == 0
    }
    
    public var count: Int {
        return nodes.count
    }
    
    public func peek() -> T? {
        return nodes.first
    }
    
    public mutating func insert(_ value: T) {
        nodes.append(value)
        shiftUp(nodes.count - 1)
    }
    
    public mutating func remove() -> T? {
        guard !nodes.isEmpty else { return nil }
        
        if nodes.count == 1 {
            return nodes.removeLast()
        } else {
            let value = nodes[0]
            nodes[0] = nodes.removeLast()
            shiftDown(0)
            return value
        }
    }
    
    public mutating func remove(at index: Int) -> T? {
        guard index < nodes.count else { return nil }
        
        let lastIndex = nodes.count-1
        if index != lastIndex {
            nodes.swapAt(index, lastIndex)
            shiftDown(from: index, until: lastIndex)
            shiftUp(index)
        }
        
        return nodes.removeLast()
    }
    
    // 변수를 직접 변경해야 하기 때문에 mutating 을 사용한다.
    private mutating func configureHeap(from array: [T]) {
        nodes = array
        
        /**
         * 힙 트리에서 n/2 - 1 은 하나 위 층위가 된다.
         * shiftDown을 하면서 자리를 잡을 것이기 때문에
         * 마지막 leaf 노드들은 할 필요가 없다.
         */
        for i in stride(from: nodes.count/2 - 1, through: 0, by: -1) {
            shiftDown(i)
        }
    }
    
    private func parentIndex(ofIndex i: Int) -> Int {
        return (i - 1) / 2
    }
    
    private func leftChildIndex(ofIndex i: Int) -> Int {
        return 2*i + 1
    }
    
    private func rightChildIndex(ofIndex i: Int) -> Int {
        return 2*i + 2
    }
    
    /**
     * shiftUp은 자신과 부모를 비교해 바꿔준다.
     */
    private mutating func shiftUp(_ index: Int) {
        var childIndex = index
        let child = nodes[childIndex] // 처음에 노드를 저장해두고 인덱스를 구한 후 바꿔준다.
        var parentIndex = self.parentIndex(ofIndex: index)
        
        while childIndex > 0 && orderCriteria(child, nodes[parentIndex]) {
            nodes[childIndex] = nodes[parentIndex]
            childIndex = parentIndex
            parentIndex = self.parentIndex(ofIndex: childIndex)
        }
        
        nodes[childIndex] = child
    }
    
    /**
     * shiftDown은 left, right 자식 중 적합한 녀석이 있으면 바꾸면서 바닥까지 내려간다.
     */
    private mutating func shiftDown(from index: Int, until endIndex: Int) {
        let leftChildIndex = self.leftChildIndex(ofIndex: index)
        let rightChildIndex = leftChildIndex + 1
        
        var first = index
        if leftChildIndex < endIndex && orderCriteria(nodes[leftChildIndex], nodes[first]) {
            first = leftChildIndex
        }
        if rightChildIndex < endIndex && orderCriteria(nodes[rightChildIndex], nodes[first]) {
            first = rightChildIndex
        }
        if first == index { return }
        
        nodes.swapAt(index, first)
        shiftDown(from: first, until: endIndex)
    }
    
    private mutating func shiftDown(_ index: Int) {
        shiftDown(from: index, until: nodes.count)
    }
    
}

 

 

'iOS > Swift' 카테고리의 다른 글

[iOS][Swift] App LifeCycle - 앱 생명주기  (0) 2024.05.24
[Swift] Extensions (확장) 이란  (1) 2024.04.12
[Swift] unrecognized selector sent to instance  (0) 2023.06.02
[Swift] Auto Layout 이란  (2) 2023.05.17
[Swift] Optional 정리  (0) 2023.01.31