Swift:错误:不能在不可变值上使用变异成员

时间:2018-03-21 02:34:32

标签: swift immutability

我在以下代码中遇到上述错误。 Heap结构来自Swift算法俱乐部。我正在使用Heap解决Hackerrank挑战:堆:找到正在运行的中位数。

import Foundation

// Enter your code here 

struct Heap<Element> {
    var elements : [Element]
    let priorityFunction : (Element, Element) -> Bool

    init(elements: [Element] = [], priorityFunction: @escaping (Element, Element) -> Bool) {
        self.elements = elements
        self.priorityFunction = priorityFunction
        buildHeap()
    }

    mutating func buildHeap() {
        for index in (0 ..< count / 2).reversed() {
            siftDown(elementAtIndex: index)
        }
    }

    var isEmpty : Bool {
        return elements.isEmpty
    }

    var count : Int {
        return elements.count
    }

    func peek() -> Element? {
        return elements.first
    }

    func isRoot(_ index: Int) -> Bool {
        return (index == 0)
    }

    func leftChildIndex(of index: Int) -> Int {
        return (2 * index) + 1
    }

    func rightChildIndex(of index: Int) -> Int {
        return (2 * index) + 2
    }

    func parentIndex(of index: Int) -> Int {
        return (index - 1) / 2
    }

    func isHigherPriority(at firstIndex: Int, than secondIndex: Int) -> Bool {
        return priorityFunction(elements[firstIndex], elements[secondIndex])
    }

    func highestPriorityIndex(of parentIndex: Int, and childIndex: Int) -> Int {
        guard childIndex < count && isHigherPriority(at: childIndex, than: parentIndex)
            else { return parentIndex }
        return childIndex
    }

    func highestPriorityIndex(for parent: Int) -> Int {
        return highestPriorityIndex(of: highestPriorityIndex(of: parent, and: leftChildIndex(of: parent)), and:     rightChildIndex(of: parent))
    }

    mutating func swapElement(at firstIndex: Int, with secondIndex: Int) {
        guard firstIndex != secondIndex
            else { return }
        elements.swapAt(firstIndex, secondIndex)
    }

    mutating func enqueue(_ element: Element) {
        elements.append(element)
        siftUp(elementAtIndex: count - 1)
    }

    mutating func siftUp(elementAtIndex index: Int) {
        let parent = parentIndex(of: index)
        guard !isRoot(index),
            isHigherPriority(at: index, than: parent)
            else { return }
        swapElement(at: index, with: parent)
        siftUp(elementAtIndex: parent)
    }

    mutating func dequeue() -> Element? {
        guard !isEmpty // 1
            else { return nil }
        swapElement(at: 0, with: count - 1) // 2
        let element = elements.removeLast() // 3
        if !isEmpty { // 4
            siftDown(elementAtIndex: 0) // 5
        }
        return element // 6
    }

    mutating func siftDown(elementAtIndex index: Int) {
        let childIndex = highestPriorityIndex(for: index) // 1
        if index == childIndex { // 2
            return
        }
        swapElement(at: index, with: childIndex) // 3
        siftDown(elementAtIndex: childIndex)
    }
}

var topHeap = Heap<Int>(priorityFunction: >)
var bottomHeap = Heap<Int>(priorityFunction: <)

let n = Int(readLine(strippingNewline: true)!)!
let val1 = Int(readLine(strippingNewline: true)!)!
print(String(format: "%.1f", Float(val1)))
if n > 1 {
    let val2 = Int(readLine(strippingNewline: true)!)!
    print(String(format: "%.1f", (Float(val1) + Float(val2)) / 2.0))
    if val1 < val2 {
        topHeap.enqueue(val1);
        bottomHeap.enqueue(val2);
    } else {
        topHeap.enqueue(val2);
        bottomHeap.enqueue(val1);    
    }
    for _ in 2..<n {
        let val = Int(readLine(strippingNewline: true)!)!

        // Put in the proper heap
        if val < topHeap.peek()! {
            topHeap.enqueue(val)
        } else if val > bottomHeap.peek()! {
            bottomHeap.enqueue(val)
        } else if topHeap.count < bottomHeap.count {
            topHeap.enqueue(val)
        } else {
            bottomHeap.enqueue(val)
        }

        // If one heap has two more than the other, move one value
        if topHeap.count == bottomHeap.count + 2 {
            var element: Int = bottomHeap.dequeue

错误:不能在不可变值上使用变异成员:'bottomHeap'是不可变的

            topHeap.enqueue(element)
        } else if bottomHeap.count == topHeap.count + 2 {
            bottomHeap.enqueue(topHeap.dequeue)

错误:不能在不可变值上使用变异成员:'topHeap'是不可变的

        }

        // If one heap has one more than the other, the top node of the larger heap holds the median
        if topHeap.count == bottomHeap.count + 1 {
            print(String(format: "%.1f", Float(topHeap.peek()!)))
        } else if bottomHeap.count == topHeap.count + 1 {
            print(String(format: "%.1f", Float(bottomHeap.peek()!)))        
        } else {
            print(String(format: "%.1f", (Float(topHeap.peek()!) + Float(bottomHeap.peek()!)) / 2.0))        
        }
    }
}

1 个答案:

答案 0 :(得分:1)

dequeue是一个功能。您需要在通话中添加()

然后,您需要处理dequeue()返回可选Int的事实。