用歐拉計劃學Rust編程(第26題)

最近想學習Libra數字貨幣的MOVE語言,發現它是用Rust編寫的,因此先補一下Rust的基礎知識。學習了一段時間,發現Rust的學習曲線很是陡峭,不過仍有快速入門的辦法。git

學習任何一項技能最怕沒有反饋,尤爲是學英語、學編程的時候,必定要「用」,學習編程時有一個很是有用的網站,它就是「歐拉計劃」,網址: https://projecteuler.netgithub

英文若是不過關,能夠到中文翻譯的網站:
http://pe-cn.github.io/編程

這個網站提供了幾百道由易到難的數學問題,你能夠用任何辦法去解決它,固然主要還得靠編程,編程語言不限,論壇裏已經有Java、C#、Python、Lisp、Haskell等各類解法,固然若是你直接用google搜索答案就沒任何樂趣了。編程語言

學習Rust最好先把基本的語法和特性看過一遍,而後就能夠動手解題了,解題的過程就是學習、試錯、再學習、掌握和鞏固的過程,學習進度會大大加快。函數

第26題

問題描述:學習

單位分數指分子爲1的分數。優化

1/6= 0.1(6) 表示0.166666…,括號內表示有一位循環節。網站

1/7= 0.(142857),1/7有六位循環節。google

找出正整數d < 1000,其倒數的十進制表示小數部分有最長的循環節。.net

經過手算找到規律,

再找一個分母大於10的:

再找一個能除盡的:

能夠發現幾個特色:

1)分子爲1,表示一開始的餘數爲1

2)餘數爲0時,表示能夠除盡,循環要終止

3)當餘數重複出現時,表示找到了循環節,2個重複出現的位置就是循環節

按照這個邏輯,循環節的長度能夠求出,這裏用兩個向量分別存儲餘數remainders和商digits。

fn reciprocal_cycle(d: u32) -> u32 {
    let mut remainders : Vec<u32> = vec![1]; //餘數
    let mut digits : Vec<u32> = vec![]; //商

    let mut numerator = 1; //分子
    while numerator != 0 {
        digits.push(numerator * 10 / d);
        numerator = numerator * 10 % d; //餘數
        let pos = remainders.iter().position(|&x| x==numerator);
        match pos {
            Some(x) => { //餘數重複出現時
                return (digits.len() - x) as u32;
            }
            None => {
                remainders.push(numerator);
            }
        }
    }
    0 //除盡的時候,表示循環節爲0
}

這裏在向量裏查找一個元素的位置索引時用了position函數,返回是一個Option 類型,用match語句針對不一樣的狀況進行處理。

主程序就簡單了:

let mut max_cycle: u32 = 0;
for n in 2..1000 {
    let rc = reciprocal_cycle(n);
    if rc > max_cycle {
        println!("n={} cycle={}", n, rc);
        max_cycle = rc;
    }
}
println!("max reciprocal cycle: {}", max_cycle);

優化:實際上商並不須要存儲,能夠減小一個向量,求循環節的函數還能夠精簡一下。

fn reciprocal_cycle(d: u32) -> u32 {
    let mut remainders : Vec<u32> = vec![1]; //餘數
    let mut numerator = 1; //分子
    while { numerator = numerator * 10 % d; numerator != 0} {
        let pos = remainders.iter().position(|&x| x==numerator);
        match pos {
            Some(x) => { //餘數重複出現時
                return (remainders.len() - x) as u32;
            }
            None => {
                remainders.push(numerator);
            }
        }
    }
    0 //除盡的時候,表示循環節爲0
}
相關文章
相關標籤/搜索