介绍
今天一个同事问如何使用python在斐波那契数列中找出与给定数字的差值绝对值最小的元素,我试着写了一下,解决了问题,现在分享出来供需要的同学参考。
1、什么是斐波那契数列
以下内容摘录自斐波那契数列的百度百科
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 3,n ∈ N*)
2、首先生成斐波那契数列(指定长度生成)
根据上面的定义可以知道如何获取一串斐波那契数列,python中实现的方式也很多,下面使用一种简单的方式实现
# 生成长度为n的斐波那契数列
def getFibonacci(n):
if not isinstance(n, int) or n < 3:
return '参数n必须为大于等于3的正整数'
a, b = 0, 1
fibList = []
i = 0
while i < n:
fibList.append(a)
a, b = b, a+b
i += 1
return fibList
调试
if __name__ == '__main__':
print('结果1:', getFibonacci(2))
print('结果2:', getFibonacci(10))
print('结果3:', getFibonacci(30))
结果1: 参数n必须为大于等于3的正整数
结果2: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
结果3: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]
说明:从上面可以看出来,数字会随着长度n原来越大,n=100时,最后一个为218922995834555169026,因此在使用的时候,如果不是特别需要,建议n不要过大。
3、在斐波那契数列中找出与给定数字的差值绝对值最小的元素及该差值绝对值
说明:下面getMinDiffValue()函数的正常返回值为一个两元素字典,第一个元素为与目标数字差值绝对值最小的数列元素,第二个为最小的差值绝对值
# 获取给定数字m与斐波那契数列元素的差值绝对值最小的元素及差值绝对值
def getMinDiffValue(targetFib, m):
# targetFib 目标斐波那契数列
# m 目标数字
try:
# 如果数字小于等于0,则最小的元素一定是0,差值绝对值为abs(m)
if m <= 0:
return {'与 %s 的差值绝对值最小的数列元素'%(str(m), ):0, '最小差值绝对值':abs(m)}
diffValueList = []
closeFibNumList = []
for i in range(0, len(targetFib)):
# 处理目标数字在斐波那契数列中存在时的情况
if targetFib[i] == m:
return {'与 %s 的差值绝对值最小的数列元素'%(str(m), ):m, '最小差值绝对值':0}
# 处理目标数字在斐波那契数列中不存在时的情况
if targetFib[i] > m:
# 获取最小的差值绝对值
closeFibNumList.append(targetFib[i - 1])
closeFibNumList.append(targetFib[i])
diffValueList.append(targetFib[i] - m)
diffValueList.append(m - targetFib[i - 1])
minDiffValue = min(diffValueList)
# 获取差值绝对值最小的元素
temAvg = sum(closeFibNumList) / 2
if m < temAvg:
targetItem = targetFib[i - 1]
elif m == temAvg:
targetItem = closeFibNumList
else:
targetItem = targetFib[i]
return {'与 %s 的差值绝对值最小的数列元素'%(str(m), ): targetItem, '最小差值绝对值': minDiffValue}
# 给定的斐波那契数列长度不足时给出提示
return '目标数字大于给定的斐波那契数列最后一位数字,长度不足,请修改斐波那契数列的长度'
except:
return '处理过程遇到异常,请确认传参正确:第一个参数为纯数字列表(要求为斐波那契数列),第二个参数为实数'
调试
if __name__ == '__main__':
print('目标斐波那契数列为:', fib)
print('结果1:',getMinDiffValue(fib, -27))
print('结果2:',getMinDiffValue(fib, 0))
print('结果3:',getMinDiffValue(fib, 8))
print('结果4:',getMinDiffValue(fib, 17))
print('结果5:',getMinDiffValue(fib, 27))
print('结果6:',getMinDiffValue(fib, 35))
print('结果7:',getMinDiffValue(fib, '3test'))
结果
目标斐波那契数列为: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
结果1: {'与 -27 的差值绝对值最小的数列元素': 0, '最小差值绝对值': 27}
结果2: {'与 0 的差值绝对值最小的数列元素': 0, '最小差值绝对值': 0}
结果3: {'与 8 的差值绝对值最小的数列元素': 8, '最小差值绝对值': 0}
结果4: {'与 17 的差值绝对值最小的数列元素': [13, 21], '最小差值绝对值': 4}
结果5: {'与 27 的差值绝对值最小的数列元素': 21, '最小差值绝对值': 6}
结果6: 目标数字大于给定的斐波那契数列最后一位数字,长度不足,请修改斐波那契数列的长度
结果7: 处理过程遇到异常,请确认传参正确:第一个参数为纯数字列表(要求为斐波那契数列),第二个参数为实数