Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我的递归函数是否由于堆栈溢出而失败?如果是,根据我的函数定义,这正常吗?_Ios_Swift_Recursion - Fatal编程技术网

Ios 我的递归函数是否由于堆栈溢出而失败?如果是,根据我的函数定义,这正常吗?

Ios 我的递归函数是否由于堆栈溢出而失败?如果是,根据我的函数定义,这正常吗?,ios,swift,recursion,Ios,Swift,Recursion,我在测试一个递归函数的性能 在第33行中,我创建了一个包含50000项的数组;数组中的每个项都是介于1和30之间的整数 当阵列的计数约>37500时,测试崩溃 我不确定这次崩溃是由于什么原因造成的,但我猜是由于堆栈溢出造成的? 事实上,这是由于堆垛流造成的吗? 给定我正在做的事情/这个上下文-这里的堆栈溢出正常吗 为方便您,下面提供了代码: let arr = (1...50000).map { _ in Int.random(in: 1...30) } func getBuild

我在测试一个递归函数的性能

在第33行中,我创建了一个包含50000项的数组;数组中的每个项都是介于1和30之间的整数

当阵列的计数约>37500时,测试崩溃

我不确定这次崩溃是由于什么原因造成的,但我猜是由于堆栈溢出造成的? 事实上,这是由于堆垛流造成的吗? 给定我正在做的事情/这个上下文-这里的堆栈溢出正常吗

为方便您,下面提供了代码:

 let arr = (1...50000).map { _ in Int.random(in: 1...30) }

    func getBuildingsWithView(_ buildings: [Int]) -> [Int]? {
        if buildings.isEmpty { return nil }
        let count: Int = buildings.count - 1
        var indices: [Int] = []
        let largest: Int = 0
        var buildings = buildings
        hasView(&buildings, &indices, largest, count)
        return indices
    }

    func hasView(_ buildings: inout [Int], _ indices: inout [Int],  _ largest: Int, _ count: Int) {
        if count > 0 {
            var largest = largest
            if (buildings[count] > largest) {
                largest = buildings[count]
            }
            hasView(&buildings, &indices, largest, count-1)
        }
        if (buildings[count] > largest) {
            indices.append(count)
        }
    }

    func test1() {
        print("-----------------TEST START - RECURSION------------------")
        measure {
            print(getBuildingsWithView(arr)!)
        }
        print("-----------------END------------------")
    }

这可能是堆栈溢出,函数hasView被草率调用,深度大约等于
count
,堆栈必须存储
count
地址,这可能会超过堆栈的大小

更多详细信息,请参阅另一篇帖子:

请注意,您实现的似乎是以相反顺序返回索引的运行最大值,这样可以更有效地实现,而不会出现如下溢出:

func runningMax(_ arr: [Int]) -> [Int] {
    var max = 0
    var out = [Int]()

    for (i, element) in arr.enumerated().reversed() {
        if element > max {
            max = element
            out.append(i)
        }
    }

    return out.reversed()
}
我将其与您的算法进行了比较,结果似乎是相同的。我还测试了高达100000000的大数值,这很好


返回的数组不需要是可选的,如果输入数组是空的,那么输出数组也是空的。

对于较小的数组,此方法是否产生正确的结果?如果是这样,那么可能是由于输入数组太大而导致堆栈溢出。@Sweeper,是的,它确实会为较小的数组生成正确的结果!我在回答中补充了细节:在调试模式下,堆栈溢出的深度为37524,在发布模式(速度优化)下,堆栈溢出的深度为130996。在编写递归实现之前,我编写了一个迭代实现。我的一个递归实现与您的相同。我决定尝试非尾部递归实现,以避免在最后调用.reversed()方法。另外:XCTests通常在完全优化的情况下运行。始终优化配置文件或使用专用的Xcode配置文件器(长时间单击运行按钮)。由于总体算法是
O(n)
,最后的
O(n)
不会改变总体复杂性(但仍会产生复制开销)。但是,您可以使用
reversed().enumerated()
如您所说,再加上返回一个反向集合而不是数组(您可以使用
some
关键字来返回一个不透明集合),以减少复制开销。让我们来看看。