【问题标题】:Bubble sorting an array in Swift, compiler error on swap在Swift中对数组进行冒泡排序,交换时编译器错误
【发布时间】:2014-10-20 02:27:03
【问题描述】:

我为纸牌游戏编写了一个非常简单的冒泡排序。它需要一个“卡片”对象数组,每个对象都有一个“顺序”属性,该属性指示要针对相关游戏进行排序的值。

以下代码在 Swift Beta 1 和 Beta 6 之间的一段时间内停止编译,我不确定为什么。

 ///Sort the cards array by order
  func sortCards(cards: Array<Card>) -> Array<Card> {
    var sorted = false
    while sorted == false {
      sorted = true
      for i in 0...cards.count - 2 {
        if cards[i].order > cards[i+1].order {
          sorted = false
          var first = cards[i]
          var second = cards[i + 1]
          cards[i] = second    //ERROR
          cards[i + 1] = first //ERROR
        }
      }
    }
    return cards
  }

发生交换的行以非常神秘的消息轰炸掉:

@!value $T5 is not identical to 'Card'

发生了什么变化,我在这里做错了什么?

额外问题:我应该如何理解错误消息?

【问题讨论】:

标签: arrays sorting compiler-errors swift


【解决方案1】:

函数参数默认是常量(就像用let声明一样)。 如果要修改函数内部的参数,则必须将其声明为变量

func sortCards(var cards: Array<Card>) -> Array<Card> { ...

注意只修改了本地参数cards,而不是作为传递的数组 函数的参数(这似乎是你的意图,因为函数 返回一个新数组)。

【讨论】:

    【解决方案2】:

    我用swift 3玩了以下。希望对来这里的人有所帮助。

    冒泡排序:

    func bubble(arr: inout [Int]) {
        for i in (1..<arr.count).reversed() {
            for j in 0..<i where arr[j] > arr[j + 1] {
                swap(&arr[j], &arr[j + 1])
            }
        }
    }
    

    使用步幅:

    func bubbleStride(arr: inout [Int]) {
        for i in stride(from: arr.count - 1, to: 1, by: -1) {
            for j in 0..<i where arr[j] > arr[j + 1] {
                swap(&arr[j], &arr[j + 1])
            }
        }
    }
    

    使用while:

    func bubbleWhile(arr: inout [Int]) {
        var i = arr.count - 1
        while(i > 0) {
            var j = 0
            while(j < i) {
                if arr[j] > arr[j + 1] {
                    swap(&arr[j], &arr[j + 1])
                }
                j += 1
            }
            i -= 1
        }
    }
    

    这可用于生成随机整数数组:

    import Cocoa
    
    func ints(cnt: Int, ceiling: Int) -> [Int] {
        let arr = Array(repeating: 0, count: cnt)
        return arr.map { _ in Int(arc4random_uniform(UInt32(ceiling))) }
    }
    

    例如:

    let a = ints(cnt: 10, ceiling: 100)
    print(a)
    
    var b = a
    bubble(arr: &b)
    print(b)
    

    输出:

    [13, 30, 68, 19, 1, 4, 28, 65, 96, 13]
    [1, 4, 13, 13, 19, 28, 30, 65, 68, 96]
    

    【讨论】:

      【解决方案3】:

      如果你像这样声明函数,那么数组是不可变的。你需要像这样使用关键字inout

      func sortCards(inout cards: Array<Card>) -> Array<Card> {
      //code
      }
      

      然后你用&amp;调用它:

      sortCards(&myArray)
      

      说明

      在 beta 过程中,Arrays 和按值/引用传递的整个模型发生了变化。

      在 beta 1 中,传递给子程序的数组只是按值传递的。只要您不更改数组的长度,按值传递的数组(和 let 数组)仍然可以修改,从而打破了按值传递的规则并允许您的原始代码工作。

      我相信在 beta 4 中,他们将数组更改为始终有效地按值传递,并且更改的常量数组(让)确实是不可修改的,这导致您的代码无法工作并在编译阶段中断。

      inout 关键字将数组更改为通过引用而不是通过值传递,并将其从使用 let 隐式定义更改为使用 var 定义,这意味着数组现在是可变的,并且对数组的更改可以通过以下方式看到调用者。

      【讨论】:

      • 我希望我能接受这两个,因为它们都是完全相关的。他们一定加强了语法检查,因为这段代码肯定在 beta 1 上工作。谢谢!
      【解决方案4】:

      这是在 swift 4.0.2 中实现的冒泡排序

      var array = [15,11,20,14,12,13,17,16,18,19]
      var sortedArray = Array(array)
      var sortedAboveIndex = array.count 
      
      for i in 0 ..< sortedAboveIndex-1 {
      
        for j in 0 ..< sortedAboveIndex-i-1 {
      
            if (sortedArray[j] > sortedArray[j+1]) {
      
                sortedArray.swapAt(j, j+1)        
            }
        }
      
      }
      
      print(sortedArray)
      

      如果对以上代码有任何疑问,请在下方评论

      【讨论】:

        【解决方案5】:

        即使数组已排序,该函数也始终运行 O(n^2) 时间。如果内部循环没有导致任何交换,则可以通过停止算法来优化它。

        func main() {
            var array: [Int] = [1, 3, 15, 6, 8, 12, 10, 33, 2, 88]
            var swapped = false
        
            for i in 0..<array.count {
                for j in 0..<array.count - i - 1 {
                    if array[j] > array[j + 1] {
        //                let temp = array[j]
        //                array[j] = array[j+1]
        //                array[j+1] = temp
                        array.swapAt(j, j + 1)
                        swapped = true
                    }
                }
        
                if swapped == false {
                    break
                }
            }
        
            print(array)
        }
        

        【讨论】:

          【解决方案6】:

          Swift 5:通用冒泡排序方法,

          func bubbleSort<T: Comparable>(with array: inout [T]) -> [T] {
              for i in 1..<array.count {
                  for j in 0..<array.count-i where array[j] > array[j+1] {
                      array.swapAt(j, j+1)
                  }
              }
              return array
          }
          

          输入:-

          var intArray = [8, 3, 5, 10, 4, -1, 17, 3, 18, 10]
          var floatArray = [12.231, 12.23, 14.5, 3.4, 67.899, 0.0, -1.234]
          var doubleArray = [123.43555, 123.1223332, -121.2212, 23.343434, 1.232434]
          var stringArray = ["Ratheesh", "Srini", "Thangu", "Muthu", "Gopi"]
          
          print(bubbleSort(with: &intArray))
          print(bubbleSort(with: &floatArray))
          print(bubbleSort(with: &doubleArray))
          print(bubbleSort(with: &stringArray))
          

          输出:-

          [-1, 3, 3, 4, 5, 8, 10, 10, 17, 18]
          [-1.234, 0.0, 3.4, 12.23, 12.231, 14.5, 67.899]
          [-121.2212, 1.232434, 23.343434, 123.1223332, 123.43555]
          ["Gopi", "Muthu", "Ratheesh", "Srini", "Thangu"]
          

          【讨论】:

            【解决方案7】:

            100% 工作测试代码

            func bubbleSort(arrValue:[Int])->[Int]{
                   var arr = arrValue
                   for i in 0..<arr.count-1{
                       for j in 0..<arr.count-i-1{
                           if arr[j] > arr[j+1]{
                               arr.swapAt(j, j+1)
                           }
                       }
                   }
                   print(arr)
                   return arr
               }
            

            【讨论】:

              猜你喜欢
              • 2016-04-04
              • 2015-04-10
              • 2013-06-10
              • 2021-09-16
              • 2012-04-14
              • 2017-01-24
              • 1970-01-01
              • 1970-01-01
              • 2015-11-01
              相关资源
              最近更新 更多