使用 Swift 语言编写递归函数以遍历 Objective C 中的 Collection 对象
Posted
技术标签:
【中文标题】使用 Swift 语言编写递归函数以遍历 Objective C 中的 Collection 对象【英文标题】:Write Recursive Function to loop through the Collection object in Objective C using Swift language 【发布时间】:2014-10-05 07:01:27 【问题描述】:我看到人们努力编写一个有效的递归函数。几乎可以肯定的是,人们不会在第一次尝试时就让递归函数正常工作。
这篇文章将帮助开发人员了解编写正确的递归函数实际上需要做什么。另外,在第一次尝试时就做好。
请看下面的答案:
【问题讨论】:
这不是一个问题。 (坦率地说,即使作为一种教育尝试,我也不认为这特别有用或有帮助。) 【参考方案1】:一般来说,考虑递归函数的一种方法是每次都要经过三个步骤:
-
确定基本情况
这是您知道停止递归的时候
它通常是函数中最简单的输入
编写一个步骤案例,使您的函数最终终止
不要担心结果
专注于让您的输入在相关意义上“更小”(更小的数字、更短的数组等)
修改step case,以便返回正确的结果
换句话说,执行一个工作单元
以计算数字的位数为例。 这可以使用尾递归来完成,尾递归是一种常见的递归。
用上面的公式:
-
我们的基本情况是单个数字;
我们的 step 案例需要使用较少位数的数字进行递归;和
我们需要确保每次实际上都在构建一个数字数组。
因此,如果我们要在 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]
在概念上没有什么比其他答案更难将其扩展到类似循环的东西了,但认为所有递归都涉及循环是错误的。
以另一个答案的递归求和序列为例,我们对每个元素做出基本/步骤决策:
-
基本情况是可以转换为浮点数的元素;
step case 是一个元素,它是一个序列;和
我们需要每次都将元素本身或其元素的递归总和添加到我们的结果中。
【讨论】:
同意!! @Sapi,感谢您的宝贵意见。【参考方案2】:什么是递归函数? 递归函数是一段代码,不断地调用自己,直到满足中断条件。
递归函数的重要方面:>
-
一个循环块(例如,for-loop)1.1 编写一个循环来迭代最顶层的集合1.2 一个 If条件,在此 if 条件中,当满足所需条件时中断循环1.3 调用递归函数以循环遍历子集合的 else 条件
在不满足中断条件时调用自身的递归函数2.1编写一个循环来迭代子集合2.2 一个 If 条件,在这个 if 条件中,当满足所需条件时中断循环2.3 一个调用 self 函数以循环遍历子集合的 else 条件
示例代码:
import UIKit
let arr1 = [1,2,3,4,5]
let arr2 = [6,7,8,9,10]
let arr3 = [11,12,13,14,15]
let arr4 = [16,17,18,19,20]
let arr5 = [arr1, arr2, 26, 27]
let arr6 = [arr3, arr4, 28]
let arrMain = [arr5, arr6, 21, 22, 23, 24, 25]
var compareNumber:Int = 5
var foundNumber:Int = 0
func recurringFunc(numbers: NSArray) -> Void
for number in numbers
"the number is \(number)"
if number is Int
if number.isEqual(compareNumber)
foundNumber = number as Int;
break
if number is NSArray
"the number is \(number)"
recurringFunc(number as NSArray)
for numbers in arrMain
numbers
if numbers is Int
"the number is \(numbers)"
if numbers.isEqual(compareNumber)
foundNumber = numbers as Int;
break
if numbers is NSArray
"the number is \(numbers)"
recurringFunc(numbers as NSArray)
foundNumber
【讨论】:
感谢您尝试提供帮助,但该代码并不是特别有用。函数什么都不返回并依赖全局变量是怎么回事?! 谢谢@Sapi。这只是一个示例代码,用于演示如何调用递归函数并摆脱它。全局变量仅用于在 Swift Playground 环境中显示输出。 你的主循环for numbers in arrMain ...
重复了递归函数的工作,可以简单地用recurringFunc(arrMain)
代替。 IE。您的配方中的第 1 点和第 2 点是相同的,通常只执行一次。 – 对输入和输出数据使用全局变量不是很好的风格,不应该在“适当的递归函数”的配方中完成。 – 您关于循环块是递归函数的重要方面的说法至少具有误导性。在这个特定的用例中这可能是正确的,但通常不是。
感谢@Martin 的指正,我最近也意识到了。以上是关于使用 Swift 语言编写递归函数以遍历 Objective C 中的 Collection 对象的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch使用 Elasticsearch Painless 脚本以递归方式遍历 JSON 字段