返回Rust中向量的最后n个元素,而不会改变向量

时间:2017-06-14 16:09:01

标签: vector rust

我正在努力寻找一种方法从矢量的末尾取两个值,对这些值求和,然后将和推送到矢量。

我发现poptruncatedrain不起作用,因为它们会删除原始矢量中的值。

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);
    }
}

3 个答案:

答案 0 :(得分:6)

您需要考虑vector 没有两个项的情况。

我会使用Iterator::revIterator::take之类的迭代器适配器,然后使用Iterator::sum结束:

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

这允许你避免显式处理vector / slice / iterator太短但代码仍然隐式处理它的情况。

您也可以直接索引切片:

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

但是,如果少于2个元素,则会发生恐慌。

在这种情况下,您可以尝试处理太短的向量,但它并不漂亮:

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);

请注意,使用Fibonacci迭代器并将其collect放入Vec可能更好。

答案 1 :(得分: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);

答案 2 :(得分:0)

要检索最后 n 个元素,您只需将其转换为切片即可。

例如获取最后 3 个元素:

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]