2017-06-14 12 views
1

ベクトルの終わりから2つの値を取り、それらの値を合計し、その合計をベクトルにプッシュする方法を見つけるのは苦労しています。ベクトルの突然変異をせずに、Rustのベクトルの最後のn個の要素を返します。

私は、poptruncate、およびdrainは、元のベクトルから値を削除するため、機能しません。

fn main() { 
    println!("Which Fibonacci number would you like to find?"); 

    let mut fib_num = String::new(); 

    io::stdin().read_line(&mut fib_num) 
     .expect("Failed to read line"); 

    let fib_num: u32 = fib_num.trim().parse() 
     .expect("Please enter a number"); 

    let mut stored_nums: Vec<u32> = vec![0, 1]; 

    while fib_num > stored_nums.len() as u32 { 
     let mut limit = stored_nums.len(); 
     let mut new_num1 = stored_nums.pop().unwrap(); 
     let mut new_num2 = stored_nums.pop().unwrap_or(0); 
     stored_nums.push(new_num1 + new_num2); 
    } 
} 
+2

'pop'は最後のものを削除し、' last'を使用して削除せずに参照でアクセスします。 – Boiethios

+0

@Boiethios lastはパラメータを取っていませんが、そうですね。私が 'blahblah.last(2)'を呼んで、完璧である最後の2つのアイテムを得ることができたら。 –

+0

それはちょっとしたアドバイスでした。 Shepmasterの答えを見てください。 – Boiethios

答えて

4

あなたはベクトル2つの項目を持っていない場合を考慮する必要があります。

私は Iterator::revIterator::takeのようなイテレータアダプタを使用して、 Iterator::sumで仕上げたい

let sum = stored_nums.iter().rev().take(2).sum(); 
stored_nums.push(sum); 

これは、あなたがベクトル/スライス/イテレータが短すぎる例明示的取り扱いを避けることができますが、コードは暗黙のうちにそれを扱います。


また、直接スライスへのインデックスができます:2つの未満の要素が存在する場合

let len = stored_nums.len(); 
let sum = stored_nums[len - 1] + stored_nums[len - 2]; 
stored_nums.push(sum); 

しかしこれは、パニックになります。

あなたは、ベクターが、この場合は短すぎることに対処しようとする可能性があり、それはかなりありません:フィボナッチイテレータを使用してよりよいだけcollectにその可能性があることを

let len = stored_nums.len(); 

let idx_a = len.checked_sub(1); 
let idx_b = len.checked_sub(2); 

let a = idx_a.and_then(|idx| stored_nums.get(idx).cloned()); 
let b = idx_b.and_then(|idx| stored_nums.get(idx).cloned()); 

let sum = a.unwrap_or(0) + b.unwrap_or(0); 

stored_nums.push(sum); 

注意をa Vec

+1

イテレーターは行く方法です。ありがとう。私はvecに2つの項目をあらかじめ入れているので、2つの項目がないかもしれないという事態を心配するとは思わなかった。シーケンスの<50番目の数字でu32がトーバイされたので、私の整数型をu64に変更しました。 –

1

あなたはVecに逆イテレータを使用することができます。

let (n1, n2) = { 
    let mut rev_iter = stored_nums.iter().rev(); 
    (rev_iter.next().unwrap().clone(), rev_iter.next().unwrap().clone()) 
}; 
stored_nums.push(n1 + n2); 
+0

イテレータが 'None'を最初に返すときに' next'を呼び出す動作は未定義です。この答えは、前のそれぞれが 'None'であるかどうかをチェックせずに' next'を複数回呼び出すので、予期しない結果につながる可能性があります。 – Shepmaster

+0

@Shepmaster私は知っています。ベクトルの長さは2以下にならず、 'next'を2回だけ呼び出すので問題ありません。 – Boiethios

+0

提供される* example *は決して2つの要素以下にはなりませんが、* question *は例よりも一般的です。 – Shepmaster

関連する問題