埃拉托斯特尼筛法与欧拉筛法:Rust 语言下的素数筛实现
素数是数学中一个古老而迷人的主题,它们在数论、密码学等领域有着广泛的应用。素数筛法是一种用于找出小于或等于给定数的所有素数的算法。本文将围绕埃拉托斯特尼筛法和欧拉筛法,使用 Rust 语言实现这两种素数筛法,并探讨其原理和性能。
埃拉托斯特尼筛法
原理
埃拉托斯特尼筛法(Sieve of Eratosthenes)是一种古老的算法,用于找出小于或等于给定数 ( n ) 的所有素数。其基本思想是从最小的素数 2 开始,将所有 2 的倍数(除了 2 本身)从序列中筛去,然后找到下一个未被筛去的数,这个数就是下一个素数,重复此过程,直到所有小于或等于 ( n ) 的数都被筛过。
Rust 实现
rust
fn sieve_of_eratosthenes(n: u32) -> Vec {
let mut is_prime = vec![true; n as usize + 1];
let mut primes = Vec::new();
for p in 2..=n {
if is_prime[p as usize] {
primes.push(p);
for multiple in (p p..=n).step_by(p) {
is_prime[multiple as usize] = false;
}
}
}
primes
}
fn main() {
let n = 100;
let primes = sieve_of_eratosthenes(n);
println!("Primes up to {}:", n);
for prime in primes {
println!("{}", prime);
}
}
性能分析
埃拉托斯特尼筛法的时间复杂度为 ( O(n log log n) ),空间复杂度为 ( O(n) )。对于较小的 ( n ),这种方法非常高效。
欧拉筛法
原理
欧拉筛法(Sieve of Euler)是埃拉托斯特尼筛法的一个变种,它利用了素数的性质来提高效率。欧拉筛法在筛选过程中,对于每个素数 ( p ),只需要将 ( p ) 的倍数标记为非素数,而不需要像埃拉托斯特尼筛法那样将所有 ( p ) 的倍数都标记。
Rust 实现
rust
fn sieve_of_euler(n: u32) -> Vec {
let mut is_prime = vec![true; n as usize + 1];
let mut primes = Vec::new();
for p in 2..=n {
if is_prime[p as usize] {
primes.push(p);
for multiple in (p 2..=n).step_by(p) {
is_prime[multiple as usize] = false;
}
}
}
primes
}
fn main() {
let n = 100;
let primes = sieve_of_euler(n);
println!("Primes up to {} using Euler's sieve:", n);
for prime in primes {
println!("{}", prime);
}
}
性能分析
欧拉筛法的时间复杂度与埃拉托斯特尼筛法相同,但空间复杂度更低,因为它不需要存储每个数的素数状态。
Rust 中的并发与并行
在 Rust 中,我们可以利用并发和并行来进一步提高素数筛法的性能。Rust 的并发模型基于所有权和借用检查,这使得它非常适合并行计算。
并行筛法
以下是一个使用 Rust 的线程池来并行实现埃拉托斯特尼筛法的示例:
rust
use rayon::prelude::;
fn sieve_of_eratosthenes_parallel(n: u32) -> Vec {
let mut is_prime = vec![true; n as usize + 1];
let mut primes = Vec::new();
for p in 2..=n {
if is_prime[p as usize] {
primes.push(p);
(p p..=n).step_by(p).for_each(|multiple| {
is_prime[multiple as usize] = false;
});
}
}
primes
}
fn main() {
let n = 100;
let primes = sieve_of_eratosthenes_parallel(n);
println!("Primes up to {} using parallel Sieve of Eratosthenes:", n);
for prime in primes {
println!("{}", prime);
}
}
在这个例子中,我们使用了 `rayon` 库来简化并行代码的编写。`rayon` 库提供了一个简单的并行迭代器,使得并行处理变得容易。
总结
本文介绍了埃拉托斯特尼筛法和欧拉筛法,并展示了如何使用 Rust 语言实现这两种算法。我们还探讨了如何利用 Rust 的并发和并行特性来提高算法的性能。通过这些实现,我们可以更好地理解素数筛法的原理,并在实际应用中发挥其优势。
Comments NOTHING