I am struggling to find a way to take two values from the end of a vector, sum those values, and push the sum to the vector.
I have found that pop
, truncate
, and drain
do not work because they remove the values from the original vector.
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);
}
}
You need to consider the case where the vector doesn't have two items.
I'd use iterator adapters like Iterator::rev
and Iterator::take
and then finish with Iterator::sum
:
let sum = stored_nums.iter().rev().take(2).sum();
stored_nums.push(sum);
This allows you to avoid explicit handling of cases where the vector / slice / iterator is too short but the code still deals with it implicitly.
You could also directly index into the slice:
let len = stored_nums.len();
let sum = stored_nums[len - 1] + stored_nums[len - 2];
stored_nums.push(sum);
This will panic if there are less than 2 elements, however.
You could attempt to deal with the vector being too short in this case, but it's a bit verbose:
fn add_last_two(nums: &[u32]) -> Option<u32> {
let len = nums.len();
let idx_a = len.checked_sub(1)?;
let idx_b = len.checked_sub(2)?;
let a = nums.get(idx_a)?;
let b = nums.get(idx_b)?;
Some(a + b)
}
fn main() {
let mut stored_nums: Vec<u32> = vec![0, 1];
let sum = add_last_two(&stored_nums).unwrap_or(0);
stored_nums.push(sum);
}
Note that it might be nicer to use a Fibonacci iterator and just collect
that into a Vec
.
You can use a reverse iterator on the 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);
To retrieve the last n elements, you could just convert it to a slice.
E.g. Get last 3 elements:
let v = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let last3 = v.as_slice()[v.len()-3..].to_vec();
println!("{:?}", last3); // [7, 8, 9]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With