Swift的地图和过滤器功能时间复杂度

时间:2018-04-17 21:02:54

标签: ios swift

我使用Swift 4以两种不同的方式实现了下面的numJewelsInStones函数。

我想比较每个实现的时间和空间复杂性。但是,我在一个实现中使用了一些本地方法,例如filtering a string,然后在另一个实现中使用mapping a string to an array of single characters。我想知道这些本机函数的时间复杂性。另外,如果我使用字符串范围来获取字符串中每个字符的出现,该怎么办?我想了解Swift中的这些本机函数如何影响整体Big O.

实施1: 过滤一个字符串(如果我忽略过滤函数我会说Big O是O(n),使用for循环,这是正确的吗?)

//J - represents types of stones that are jewels
//S - represents the stones I have
func numJewelsInStones(_ J: String, _ S: String) -> Int { 
    var sum = 0 //Sum - represents how many of the stones I have are also jewels
    for jewel in J {
        sum = sum + S.filter {$0 == jewel}.count //add sum of occurrences for each stone that is a jewel
    }
    return sum 
}
print(numJewelsInStones("aA", "aAAbbbb")) //prints 3
print(numJewelsInStones("z", "ZZ"))       //prints 0

实施2: 我做的第一件事是将字符串映射到单个字符数组,否则我会得到错误'无法在行counts[stone] = (counts[stone] ?? 0) + 1 <上使用类型为字符的索引子类型字符串[String:Int]的子字符串/ p>

UPDATE:只是注意到我意识到我甚至不需要将字符串映射到字符数组,如果我只是将计数字典的定义更改为var counts: [Character: Int] = [:]以避免上面的错误。哎呀。我是为了这个问题而原样离开的。

func numJewelsInStones2(_ J: String, _ S: String) -> Int {
        let jewels = J.map { String($0) }
        let stones = S.map { String($0) }
        var counts: [String: Int] = [:]
        var sum = 0
    for stone in stones {
        counts[stone] = (counts[stone] ?? 0) + 1 //frequency count dict
    }
    for jewel in jewels { //for every jewel
        if let count = counts[jewel]  { //if the jewel exists in the frequency count dict
            sum = sum + count //add its count to the total sum
        }
    }
    return sum
}

print(numJewelsInStones2("aA", "aAAbbbb")) //prints 3
print(numJewelsInStones2("z", "ZZ"))       //prints 0

2 个答案:

答案 0 :(得分:4)

Swift标准库中的所有高阶函数,例如mapflatMap / compactMapfilterreduce都有{{1}一般来说,时间复杂度,因为所有这些都在他们被调用的完整集合上工作,他们只访问每个元素一次,因此它们具有线性时间复杂度。

考虑到这一点,您的第一个实施具有O(n)时间复杂度,因为O(J*S)中的每个元素都使用J遍历S的所有元素。

另一方面,您的第二个实现具有大致线性的时间复杂度,具体取决于filter中有StringCharacterSJ,其时间复杂度为O(J)O(S),因为您没有任何嵌套循环,所以您只能顺序遍历JS

实施1或2是否更有效取决于JS的大小。

答案 1 :(得分:1)

flatMap / compactMapO(m + n),其中n是此序列的长度,而m是结果的长度。

这是用iOS SDK文档编写的。