Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看一个小问题:斐波那契序列。
提问
提供一个方法,该方法返回一个迭代器,该迭代器可以生成无限量的连续斐波那契数。
模板:
use num::BigUint;
fn all_fibonacci_numbers() -> impl Iterator<Item = BigUint> {
todo!()
}
分析
如果读者现在不知道什么是斐波那契数列,可以先自行搜索一下,我这里给出一部分链接:斐波那契数列
观察模板,返回的是一个迭代器(rust中的迭代器),因为斐波那契数列的增长速度非常快,所以该迭代器的关联类型是BigUnit。
在已经掌握一部分基本知识之后,我们来分析下斐波那契数列的生成规则:
- 起始初始化两个数,
a,b都赋值为1。 - 每次调用
next时,先返回a的值。 - 令
t等于a的值,a等于b的值,b等于t + b。 - 重复2-3过程。
模拟:
- 调用
next,返回a的值:1。执行过程3,此时a为1,b为2。 - 调用
next,返回a的值:1。执行过程3,此时a为2,b为3。 - 调用
next,返回a的值:2。执行过程3,此时a为3,b为5。 - 调用
next,返回a的值:3。执行过程3,此时a为5,b为8。 - 继续······
解决方案
use num::BigUint;
struct Fibonacci(BigUint, BigUint);
impl Iterator for Fibonacci {
type Item = BigUint;
fn next(&mut self) -> Option<Self::Item> {
let cur = self.0.clone();
self.0 = self.1.clone();
self.1 = cur.clone() + self.1.clone();
Some(cur)
}
}
pub fn all_fibonacci_numbers() -> impl Iterator<Item = BigUint> {
Fibonacci(BigUint::from(1u32), BigUint::from(1u32))
}
此处借助了一个结构体,用于存储两个数,其实是可以不用的。
Trick
- 通过实现
traitIterator返回一个迭代器。 - 该迭代器只需要实现
next方法即可,就可以运作。 - 为了防止数越界,使用
BigUint。