如何将Option <Box <ListNode >>的链接列表转换为Vec <i32>?

时间:2019-07-06 13:54:52

标签: rust

我想将以下Option<Box<ListNode>>类型转换为Vec<i32>类型:

fn main() {
    Some(ListNode {
        val: 3,
        next: Some(ListNode {
            val: 4,
            next: Some(ListNode { val: 2, next: None }),
        }),
    })
}

我想实现list_to_vec函数:

#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
    pub val: i32,
    pub next: Option<Box<ListNode>>,
}

impl ListNode {
    pub fn new(val: i32) -> Self {
        ListNode { next: None, val }
    }

    pub fn vec_to_list(mut value: Vec<i32>) -> Option<Box<ListNode>> {
        match value.pop() {
            Some(x) => Some(Box::new(ListNode {
                val: x,
                next: ListNode::vec_to_list(value),
            })),
            None => None,
        }
    }
    pub fn list_to_vec(mut value: &Option<ListNode>) -> Vec<i32> {
        //????????????????????????????
    }
}

所需的输出

[3, 4, 2]

我尝试过:

pub fn list_to_vec(mut value: &Option<ListNode>) -> Vec<i32> {
    let mut v = vec![];
    match value {
        Some(x) => {
            &v.push(x.val);
            Self::list_to_vec(x.next)
        }
        None => v,
    }
}
let h = ListNode::vec_to_list(vec![2, 4, 3]);
println!("{:#?}", ListNode::list_to_vec(&h));

它有一个错误:

error[E0308]: mismatched types
  --> src\main.rs:27:56
   |
27 |           Some(x) => {&v.push(x.val);Self::list_to_vec(x.next)},
   |                                                        ^^^^^^ expected reference, found enum `std::option::Option`
   |
   = note: expected type `&std::option::Option<ListNode>`
              found type `std::option::Option<std::boxed::Box<ListNode>>`

error[E0308]: mismatched types
  --> src\main.rs:74:40
   |
74 | println!("{:#?}",ListNode::list_to_vec(&h));
   |                                        ^^ expected struct `ListNode`, found struct `std::boxed::Box`
   |
   = note: expected type `&std::option::Option<ListNode>`
              found type `&std::option::Option<std::boxed::Box<ListNode>>`

3 个答案:

答案 0 :(得分:0)

我解决了。

pub fn list_to_vec(mut value: Option<Box<ListNode>>, mut v_cup: Vec<i32>) -> Vec<i32> {
    match value {
        Some(x) => {
            v_cup.push(x.val);
            Self::list_to_vec(x.next, v_cup)
        }
        None => v_cup,
    }
}
let h = ListNode::vec_to_list(vec![2, 4, 3]);
let v_cup = vec![];
println!("{:?}", ListNode::list_to_vec(h, v_cup));

答案 1 :(得分:0)

这里不需要递归解决方案,它可能不如迭代解决方案有效。

拥有所有权:

pub fn list_to_vec(mut value: Option<Box<ListNode>>) -> Vec<i32> {
    let mut v = Vec::new();
    while let Some(n) = value {
        v.push(n.val);
        value = n.next;
    }
    v
}

参考:

pub fn list_to_vec(mut value: &Option<Box<ListNode>>) -> Vec<i32> {
    let mut v = Vec::new();
    while let Some(n) = value {
        v.push(n.val);
        value = &n.next;
    }
    v
}

答案 2 :(得分:0)

如果不执行尾部递归功能,您将不堪重负,function无法处理中等大小的向量。对于您的vec_to_list(),您可以实施list_to_vec()并将其收集起来,这个例子又快又肮脏:

Iterator