返回Vec的递归函数

时间:2017-09-20 16:23:08

标签: recursion rust flatten

我继续挣扎着递归的概念。我有一个函数,它接受u64并返回该整数的Vec<u64>个因子。我想在Vec中的每个项目上递归调用此函数,返回展平Vec,直到函数为每个项返回Vec<self>,即每个项目都是素数。

fn prime_factors(x: u64) -> Vec<u64> {
    let factors = factoring_method(x);
    factors.iter().flat_map(|&i| factoring_method(i)).collect()
}

The complete code

这仅返回最终迭代的Vec个因子,并且没有条件允许它继续前进,直到项目全部为素数。

factoring_method是我非常满意的正方形的一致性。我确定有很多优化空间,但我希望在重构之前完成工作版本。我认为递归应该在congruence_of_squares中 - 在它返回的Vec的每个成员上调用自己,但是我不确定如何构造条件以防止它无限地这样做。 / p>

1 个答案:

答案 0 :(得分:0)

有用的递归需要两件事:

  1. 函数直接或间接调用自身。
  2. 有一些终止案例。
  3. 数字的素数因子分解的一个定义是:

    • 如果数字是素数,那么这是唯一的主要因素
    • 否则,结合一对数字因素的素因子

    由此,我们可以识别终止条件(“如果它是素数”)和递归调用(“因素的主要因素”)。

    请注意,我们还没有编写任何代码 - 到目前为止,所有内容都是概念性的。

    然后我们可以将这个想法转录为Rust:

    fn prime_factors(x: u64) -> Vec<u64> {
        if is_prime(x) {
            vec![x]
        } else {
            factors(x).into_iter().flat_map(prime_factors).collect()
        }
    }
    

    这里有趣的作品:

    • 我们使用into_iter来避免取消引用迭代值。
    • 我们可以直接传递函数名作为闭包,因为类型为align。

    一些(效率低下的)辅助函数完善了实现:

    fn is_prime(x: u64) -> bool {
        !(2..x).any(|i| x % i == 0)
    }
    
    fn factors(x: u64) -> Vec<u64> {
        match (2..x).filter(|i| x % i == 0).next() {
            Some(v) => vec![v, x / v],
            None => vec![],
        }
    }