在Swift中填充多维数组

4

我是Swift的新手,遇到了一个Swift语言问题。

我需要编写一个函数,创建一个N x N的二维矩阵并找到对角线上元素的和。但我在将数组填充为随机值方面遇到了一些问题。

这是我的代码:

import Foundation
func diagonal (N:Int) {
    var array: [[Int]] = [[0],[0]]
    for row in 0...N {
        for col in 0...N {
            var z = Int(arc4random_uniform(100))
            array[row][col] = z
        }
    }
    println (array)
}    

它不起作用。

所以我期待着你的帮助。


1
有什么问题吗?你是否收到任何错误信息? - ABakerSmith
没有错误。最后的 for 循环(for col in 0...N)只执行了两次。 - eserdk
4个回答

7

@Matt的回答提到了您当前代码的一些好处,并强调了您需要解决的问题。我想提供一个填充二维数组的替代方案。而不是用零来填充数组,然后设置每行/列的值,您可以使用append添加新值,例如:

func diagonal (N:Int) {
    var array: [[Int]] = []

    for row in 0..<N {
        // Append an empty row.
        array.append([Int]())

        for _ in 0..<N {
            // Populate the row.
            array[row].append(Int(arc4random_uniform(100)))
        }
    }

    println(array)
}

使用它:

diagonal(2)
// [[40, 58], [44, 83]]

我完全支持这个。这正是我说我的代码不是唯一的或最好的方式时所想表达的。我只是试图通过逐行对比来展示原始代码中明显存在的问题。 - matt
我知道这是一篇旧帖子...现在在Swift 5中,你必须使用:diagonal(N:2)来调用该函数,或者你必须更改头部为:func diagonal(_ N:Int){ - BlindSide

4
你说的是:
array[row][col] = z

在Swift中不存在"稀疏"数组。如果row不存在——也就是说,如果array[row]引用一个大于array的最后一个已存在索引的索引——那么你将会崩溃。你不能简单地对array[row][col]进行赋值并期望魔法发生;你必须确保array[row][col] 存在
另外一个问题是你混淆了范围运算符.....<。在你的循环中for row in 0...N,你将会循环N+1次,就好像这些数组由N+1个元素组成一样。这可能不是你想要的;你可能打算让N表示元素的数量。所以你需要使用..<代替。
因此,为了总结我刚才所说的一切并付诸实践,你可以像这样替换相关的三行代码,这样你的代码就能够顺利运行了:
var array: [[Int]] = Array(count:N, repeatedValue:Array(count:N, repeatedValue:0))
for row in 0..<N {
    for col in 0..<N {

那并不是你尝试做的事情的唯一方式,甚至也不是最好的方式,但至少它是有意义的,而你的代码却无法承认这一点!


是的,我已经阅读了你在这里写的内容。我正在寻找不使用“repeatedValue”的方法。谢谢你提供的范围运算符 :) 我会尝试你和@ABakerSmith的两种方法。非常感谢! - eserdk

0
public func  getLine() -> String {

    var buf = String()
    var c = getchar()

    while c != EOF && c != 10 {
        buf.append(Character(UnicodeScalar(UInt32(c))!))
        c = getchar()
    }
    return buf
}


print("Enter value of Rows and Coloums :")

let rows = Int(getLine())
let coloums = Int(getLine())

print("Enter values in Array(rows * coloums):")

var array = [[Int]]()

for i in 0 ..< (rows ?? 0){

    var rowArray = [Int]()

    for j in 0 ..< (coloums ?? 0) {

        rowArray.append(Int(getLine())!)
    }

    array.append(rowArray)
}

print(array)

0
上面的两个答案涵盖了所有要点并纠正了OP遇到的问题。然而,它们有点过时且缺乏灵活性。
以下提供了一个自定义初始化器在[Int]上,以支持用随机值填充2D数组。
extension Array where Element == [Int] {
    init(row: Int, col: Int, min: Int, max: Int) {
        precondition(min <= max)
        self.init()
        for index in 0..<row { 
            append([Int]())
            for _ in 0..<col {
                self[index].append(Int.random(in: min...max))
            }
        }
    }
}

快速概述正在发生的事情:

  1. Precondition 确保 min 值不超过 max,否则您的随机函数将崩溃
  2. 创建一个空的 [Int]
  3. 它迭代行数,创建一个空的 [Int] 并将其添加到自身
  4. 然后再次迭代每个列,在其中添加定义范围内的随机 Int

您可以使用以下方式调用它:

let matrix = [[Int]](row: 10, col: 10, min: 0, max: 99)

另外,如果您想要行和列的数量相等,您可以创建另一个初始化函数来接受单个大小参数,然后调用此函数(或者只需将行/列替换为大小)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接