Recursion 使用Swift语言编写递归函数以循环遍历目标C中的集合对象
我见过人们努力编写一个有效的递归函数。几乎可以肯定的是,人们在第一次尝试时并没有让递归函数正常工作 这篇文章将帮助开发人员理解编写正确的递归函数实际需要做什么。另外,在第一次尝试时要正确 请看下面的答案:什么是递归函数?Recursion 使用Swift语言编写递归函数以循环遍历目标C中的集合对象,recursion,swift,swift-playground,generics,Recursion,Swift,Swift Playground,Generics,我见过人们努力编写一个有效的递归函数。几乎可以肯定的是,人们在第一次尝试时并没有让递归函数正常工作 这篇文章将帮助开发人员理解编写正确的递归函数实际需要做什么。另外,在第一次尝试时要正确 请看下面的答案:什么是递归函数? 递归函数是一个代码块,它一次又一次地调用自己,直到满足中断条件为止 递归函数的重要方面: 循环块(例如,用于循环) 1.1编写一个循环以迭代最顶层的集合 1.2 If条件,在该If条件内,当满足所需条件时,断开回路 1.3调用递归函数以在子集合中循环的else条件 当中断条件不
递归函数是一个代码块,它一次又一次地调用自己,直到满足中断条件为止 递归函数的重要方面:
1.1编写一个循环以迭代最顶层的集合
1.2 If条件,在该If条件内,当满足所需条件时,断开回路
1.3调用递归函数以在子集合中循环的else条件
2.1编写循环以迭代子集合
2.2 If条件,在该If条件内,当满足所需条件时,断开回路
2.3调用self函数以循环子集合的else条件
一般来说,考虑递归函数的一种方法是每次都要经过三个步骤:
- 这是您知道停止递归的时候
- 它通常是函数的最简单的输入
- 现在还不用担心结果
- 专注于使您的输入在相关意义上“更小”(更小的数字、更短的数组等)
- 换句话说,执行一个工作单元
以计算数字的位数为例。 这可以使用尾部递归来完成,尾部递归是一种常见的递归 根据上述公式:
因此,如果我们在Swift中实现这一点,我们将得到一个概念上简单的结果:
extension Int {
func digitsInBase(base: Int) -> [Int] {
/*
* Check for the 'base case', ie the simplest input
* We can immediately deal with this situation
*/
if self < base {
return [self]
}
/*
* Here, we have the 'step case'
* The idea is to break the problem into small parts, while
* making sure we get a bit closer to the base case each time
*/
return (self/base).digitsInBase(base) + [self%base]
}
// convenience property for a common base
var digits: [Int] {
return self.digitsInBase(10)
}
}
123.digits // [1, 2, 3]
7.digitsInBase(2) // [1, 1, 1]
extension Int{
func数字数据库(基:Int)->[Int]{
/*
*检查“基本情况”,即最简单的输入
*我们可以立即处理这种情况
*/
如果self
从概念上讲,没有什么比将其扩展到循环更困难的了,正如另一个答案所做的那样,但是认为所有递归都涉及循环是错误的 以另一个答案的递归求和序列为例,我们对每个元素进行基本/步骤决策:
这不是一个问题。(坦率地说,即使是作为一种教育尝试,我也不认为这是特别有用或有帮助的。)我很感激您试图提供帮助,但代码并不是特别有用。函数什么也不返回,依赖全局变量?!谢谢@Sapi。这只是一个示例代码,演示如何调用递归函数并中断它。全局变量仅用于在Swift游乐场环境中显示输出。arrMain{…}中数字的主循环
重复递归函数的工作,可以简单地替换为recurringFunc(arrMain)
。也就是说,配方中的第1点和第2点是相同的,通常只实施一次对输入和输出数据同时使用全局变量不是一种好的风格,不应该按照“适当的递归函数”的方法来做您关于循环块是递归函数的一个重要方面的说法至少是误导性的。这在这个特定的用例中可能是正确的,但不是一般的。谢谢你的更正@Martin,我最近也意识到了。同意@Sapi,谢谢你的宝贵意见。
extension Int {
func digitsInBase(base: Int) -> [Int] {
/*
* Check for the 'base case', ie the simplest input
* We can immediately deal with this situation
*/
if self < base {
return [self]
}
/*
* Here, we have the 'step case'
* The idea is to break the problem into small parts, while
* making sure we get a bit closer to the base case each time
*/
return (self/base).digitsInBase(base) + [self%base]
}
// convenience property for a common base
var digits: [Int] {
return self.digitsInBase(10)
}
}
123.digits // [1, 2, 3]
7.digitsInBase(2) // [1, 1, 1]