今天用swift实现了一些常见的递归函数,给大家分享下:
1.n的阶乘,这个就不赘述了
代码:
func recursive(n: UInt) -> UInt{
if n == 0{
return 1
} else {
var result = n * recursive(n - 1)
return result
}
}
测试代码:5的阶乘
var result = recursive(5)
println("result = \(result)")
结果:
result = 120
2.汉诺塔,源于印度的一种益智玩具,其实跟咱们中国的九连环玩法是一个道理的,题如下:
分析: 假设珠子从上到下依次为a,b,c,d…. 辅助杆为2号杆
1个珠子:把a从1号杆直接移到3号杆;
2个珠子:先把a从1号杆移到2号杆,然后把b移到3号杆,再把a移到3号杆;
3个珠子:先把ab从1号杆移到2号杆(要借助3号杆,因为只能大珠子在下),然后把c从1号杆移到3号杆,然后把ab从2号杆移到3号杆(借助1号杆)
n个珠子:先把n-1从1号移到2号(要借助3号,因为只能大珠子在下),然后把n从1号杆移到3号杆,然后把n-1从2号杆移到3号杆(要借助1号杆)
明显这也是一个递归问题
代码:
声明所需的总步数:
var step = 0
每移动一个珠子调用的函数:
func move(index: UInt, from: String, to: String){
step++
println("第\(step)步:把第\(index)个珠子从\(from)号杆移到\(to)号杆。")
}
汉诺塔函数:
func hanoi(n: UInt, from: String, to: String, depend: String){
if n == 1{
move(1, from: from, to: to)
} else{
hanoi(n - 1, from: from, to: depend, depend: to)
move(n, from: from, to: to)
hanoi(n - 1, from: depend, to: to, depend: from)
}
}
测试代码:上题中有3个珠子,n为3,from为1号杆,to为3号杆,借助杆depend为2号杆
hanoi(3, from: "1", to: "3", depend: "2")
结果:
第1步:把第1个珠子从1号杆移到3号杆。
第2步:把第2个珠子从1号杆移到2号杆。
第3步:把第1个珠子从3号杆移到2号杆。
第4步:把第3个珠子从1号杆移到3号杆。
第5步:把第1个珠子从2号杆移到1号杆。
第6步:把第2个珠子从2号杆移到3号杆。
第7步:把第1个珠子从1号杆移到3号杆。
3.全序列: 总共有n的阶乘个排列
分析:
1.试想,我们只有两个数字:12.要对它进行全排列,第一种方式就是12本身,第二种,将12交换,变为21即可。这提示了我们一种交换的思路。
2.但这概括的并不全面。试想,我们要对123进行全排列。我们可以采用将1固定,“23”进行全排列,将“2”固定,对“13”进行全排列。将“3”固定,对“12”进行全排列。
这其实就是首部为”1“,然后是“2”,然后是“3”,不就是第二位后边的数依次和第一位进行交换么?这是典型的递归的思路。
3.但是,这样也不全面,我们每次交换要将排列恢复成为原始的“123”,因为这个算法求排列的时候,前后并没有依赖性,其参考物只有“123”这个原始的第一个排列。否则,如果我们不恢复的话,就会出现,虽然数量与正确解法相同,但是会有重复的排列的现象。
代码:
交换函数swap
//传入参数如果需要修改,需要添加inout
func swap<T>(inout array: [T], index1: Int, index2: Int){
var temp = array[index1]
array[index1] = array[index2]
array[index2] = temp
}
全序列排序函数,传入参数为数组,开始位置和结束位置
func allRange<T>(inout array: [T], start: Int, end: Int){
//start end相等表示替换到了最后一个值,排序完成
if start == end{
println(array)
} else{
for (var i = start; i <= end; i++){
//先用第一个数跟后面的交换
swap(&array, index1: start, index2: i)
//递归第一个数后面的
allRange(&array, start: start + 1 , end: end)
//还原为初始数组
swap(&array, index1: start, index2: i)
}
}
}
测试代码:数组为[“1”, “2”, “3”, “4”]
var stringArray = ["1", "2", "3", "4"];
allRange(&stringArray, start: 0, end: stringArray.count - 1)
4.斐波那契数列 (一个数等于它前面两个数的和)
一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么n个月以后可以繁殖多少对兔子?
分析如下:(记得算上老兔子每个月都能生小兔子)
第一个月小兔子没有繁殖能力,所以还是一对;
两个月后,生下一对小兔子,总数共有两对;
三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,总数共是三对;
如此类推:1,1,2,3,5,8,13。。。
代码:
func fib(#month: UInt) -> UInt{
if month == 0{
return 1
} else if month == 1{
return 1
} else {
var cout = fib(month: month - 1) + fib(month: month - 2)
return cout
}
}
测试代码:12个月会有多少只兔子?
var allCount = fib(month: 12)
println("总共有兔子\(allCount)对。")
今天先到此为止,稍后我会继续写下去,有写的不对的地方请大家多多指出,大家共同进步,谢谢。