我继续挣扎着递归的概念。我有一个函数,它接受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()
}
这仅返回最终迭代的Vec
个因子,并且没有条件允许它继续前进,直到项目全部为素数。
factoring_method
是我非常满意的正方形的一致性。我确定有很多优化空间,但我希望在重构之前完成工作版本。我认为递归应该在congruence_of_squares
中 - 在它返回的Vec
的每个成员上调用自己,但是我不确定如何构造条件以防止它无限地这样做。 / p>
答案 0 :(得分:0)
有用的递归需要两件事:
数字的素数因子分解的一个定义是:
由此,我们可以识别终止条件(“如果它是素数”)和递归调用(“因素的主要因素”)。
请注意,我们还没有编写任何代码 - 到目前为止,所有内容都是概念性的。
然后我们可以将这个想法转录为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
来避免取消引用迭代值。一些(效率低下的)辅助函数完善了实现:
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![],
}
}