rust實現斐波那契數列

使用Rust做斐波那契數列

用了Rust優化意識更強烈了,總想把代碼優化到極致

1、遞歸版本

fn fb(i: i32) -> i32 {
    if i <= 0 {
        panic!("索引要大於0");
    }
    return if i <= 2 { 1 } else { fb(i - 1) + fb(i - 2) };
}

2、非遞歸版本

fn fb_use_loop(mut n: i32) -> i32 {
    if n <= 0 {
        panic!("索引要大於0");
    }
    let mut p1 = 1;
    let mut p2 = 0;
    let mut now = 1;
    while n > 0 {
        now = p1 + p2;
        p1 = p2;
        p2 = now;
        n -= 1;
    }
    return now;
}

3、利用編譯器檢查的unsigned版本

編譯器會自動檢查傳入的值,如果是負數就會報錯。嚴格意義上代碼還有一個小問題,那就是fb(0)會是1,斐波那契數列理論上是不存在0的,但是不影響其它的結果都是正確的。此外還有整數溢出錯誤,這個和之前的都存在,但是斐波那契增長還是挺快的,要避免這個問題似乎也沒有什麼意義,總有更大的數讓你溢出。如果是普通的題目,u32(4294967295)應該夠了。rust的這個 return if else語法糖真的很方便。

fn fb(i: u32) -> u32 {
    return if i <= 2 { 1 } else { fb(i - 1) + fb(i - 2) };
}
fn fb_use_loop(mut n: u32) -> u32 {
    let mut p1 = 1;
    let mut p2 = 0;
    let mut now = 1;
    while n > 0 {
        now = p1 + p2;
        p1 = p2;
        p2 = now;
        n -= 1;
    }
    return now;
}

4、急速體驗

通過使用一個vector來對已經計算出來的斐波那契數列進行緩存。

struct Fb {
    cache: Vec<usize>,
}
impl Fb {
    fn new() -> Fb {
        return Fb {
            cache: vec![0, 1, 1],
        };
    }
    fn at(&mut self, n: usize) -> usize {
        return match self.cache.get(n) {
            Some(num) => *num,
            None => {
                // None時n總是大於2的,因爲new中已經初始化了cache
                let v = self.at(n - 1) + self.at(n - 2);
                self.cache.push(v);
                v
            }
        };
    }
}

使用時只需要:

    let mut fb_cached = Fb::new();
    println!("{}", fb_cached.at(12));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章