[炼手Rust]斐波那契序列

297 阅读2分钟

Hi,大家好,这里是炼手Rust专栏,我是xiaoK,今天来看一个小问题:斐波那契序列。

spiral.jpg

提问

提供一个方法,该方法返回一个迭代器,该迭代器可以生成无限量的连续斐波那契数。

模板:

use num::BigUint;

fn all_fibonacci_numbers() -> impl Iterator<Item = BigUint> {
    todo!()
}

分析

如果读者现在不知道什么是斐波那契数列,可以先自行搜索一下,我这里给出一部分链接:斐波那契数列
观察模板,返回的是一个迭代器(rust中的迭代器),因为斐波那契数列的增长速度非常快,所以该迭代器的关联类型是BigUnit
在已经掌握一部分基本知识之后,我们来分析下斐波那契数列的生成规则:

  1. 起始初始化两个数,ab都赋值为 1
  2. 每次调用next时,先返回a的值。
  3. t等于a的值,a等于b的值,b等于t + b
  4. 重复2-3过程。

模拟:

  1. 调用next,返回a的值:1。执行过程3,此时a1b2
  2. 调用next,返回a的值:1。执行过程3,此时a2b3
  3. 调用next,返回a的值:2。执行过程3,此时a3b5
  4. 调用next,返回a的值:3。执行过程3,此时a5b8
  5. 继续······

解决方案

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

  1. 通过实现trait Iterator返回一个迭代器。
  2. 该迭代器只需要实现next方法即可,就可以运作。
  3. 为了防止数越界,使用BigUint