递归的更好方法?

时间:2016-12-31 04:05:46

标签: swift

我在Swift Playgrounds中构建了这个代码示例,作为我正在进行的大型项目的一部分概念验证。我需要做的是传递一系列选项(由optionsArray或testArray表示),其中每个int是可用选项的数量。这些选项最终将构建到3亿多个单独的PDF和HTML文件中。该代码目前正在运行,并列出了我想要的大量可能性。

我的问题是:有没有更好的方法来处理这种情况?有更优雅或更有效的东西吗?这是将在应用程序或任何内容上运行的东西,它将从命令行运行并占用它所需的所有时间,但如果有更好的方法来提高性能或稳定性我和# 39;全是耳朵。

我已经知道的事情:它无法处理从数组中出来的值0。阵列是一个常数,所以它不会偶然发生。线下代码处理事物的方式,0是一个无意义的值。每个元素代表可用选项的数量,因此2基本上是布尔值,1仅为 false 。因此,如果我需要占位符元素以供将来扩展,它们的值为1并在输出中显示为0。

此外,最终产品不仅仅将文本作为输出barf到控制台,它将根据permutationEnding()数组在currentOptions函数中写入文件。

let optionsArray: [Int] = [7,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2]
let testArray: [Int] = [7,2,3,2]
var currentOptions: [Int] = []
var outputString: String = ""
func buildPermutations(array: Array<Int>) {
    currentOptions.removeAll()
    permutationRecursion(array: array, index: 0)
}
func permutationRecursion(array: Array<Int>, index: Int) {
    for i in 1 ... array[index] {
        currentOptions.append(Int(i-1))
        if array.count > (index + 1) {
            permutationRecursion(array: array, index: index + 1)
        } else {
            permutationEnding()
        }
        currentOptions.removeLast()
    }
}
func permutationEnding() {
    for i in 1 ... currentOptions.count { // Output Elements
        outputString += String(currentOptions[i-1])
    }
    outputString += "\n" // Goes after output elements closing bracket.
}
// buildPermutations(array: optionsArray) 
buildPermutations(array: testArray)
print(outputString)

思想?

1 个答案:

答案 0 :(得分:0)

我想我已经弄明白你要做什么了。您需要每个可能的整数组合的字符串输出,该组合可以映射决策树上的所有可能路线。

我把它归结为四到五行。

let n = testArray.count // for readability
let products = ([Int](1...n)).map({testArray[$0..<n].reduce(1, *)})

// products is the cross product of element i + 1 to  element n of the array for all i in the array

let zipped = zip(testArray, products)

for i in 0..<testArray.reduce(1, *) { // this reduce is the cross product of the whole array

    let treePath = zipped.map(){ String(i / $0.1 % $0.0) }.joined()
    outputString += treePath + "\n"
}

还有一个编辑:我认为对于像NumPy这样的奇特矩阵操作,这可能会更快。我想知道Accelerate框架是否可以为你做一些魔术,但我没有使用它。

编辑:我很好奇所以我用这个测试数组计时

let testArray: [Int] = [7,2,2,2,2,2,2,3,2]

问题中的递归函数是:132.56 s

这里的拉链图是:14.44 s

当我向测试数组中添加元素时,它似乎是指数级的。