因数/质因数算法
找出n的因数
一半(小)
fn factor(n: usize) -> Vec<usize> {
(1..).take_while(|i| i * i <= n)
.filter(|x| n%x ==0)
.collect::<Vec<usize>>()
}
全部
fn factor_full(n: usize) -> Vec<(usize,usize)> {
(1..).take_while(|i| i * i <= n)
.filter(|x| n%x ==0)
.map(|x| (x, n/x))
.collect::<Vec<(usize,usize)>>()
}
求n的质因数序列
fn factor_primes(n: usize) -> Vec<usize> {
let mut a = 2;
let mut m = n;
let mut result = Vec::new();
for i in a..=m {
while n != i {
if m % i == 0 {
let t: usize = *result.last().unwrap_or(&0);
if t != i {
result.push(i);
}
m = m / i
} else {
break;
}
}
}
if result.len() == 0 {
return vec![1,n];
}
result
}
分解质因数 算法同上
fn factor_primes(n: usize) -> Vec<usize> {
let mut a = 2;
let mut m = n;
let mut result = Vec::new();
for i in a..=m {
while n != i {
if m % i == 0 {
result.push(i);
m = m / i
} else {
break;
}
}
}
if result.len() == 0 {
return vec![1,n];
}
result
}
参考链接
素数算法
找出n内的素数
use std::collections::HashMap;
fn find_primes(n: usize) -> Vec<usize> {
let mut result = Vec::new();
let mut is_prime = HashMap::new();
is_prime.insert(2, true);
is_prime.insert(3, true);
is_prime.insert(5, true);
is_prime.insert(7, true);
for i in 2..=n {
let is_pr = is_prime.entry(i).or_insert(true);
if *is_pr {
result.push(i);
}
((i * 2)..=n).step_by(i).for_each(|x| {
is_prime.entry(x).or_insert(false);
});
}
result
}
vec版本, 实测速度更快, 空间略大
fn find_primes(n: usize) -> Vec<usize> {
let mut result = Vec::new();
let mut is_prime = vec![true; n + 1];
for i in 2..=n {
if is_prime[i] {
result.push(i);
}
((i * 2)..=n).step_by(i).for_each(|x| {
is_prime[x] = false;
});
}
result
}
参考链接
线性筛选法
fn find_primes(n: usize) -> Vec<usize> {
let mut result = vec![0; n + 1];
let mut is_prime = vec![true; n + 1];
let mut count = 0;
for i in 2..=n {
if is_prime[i] {
result[count] = i;
count += 1;
}
let mut j = 0;
while result[j] * i <= n {
is_prime[result[j] * i] = false;
if (i % result[j]) == 0 {
break;
}
j += 1;
}
}
result.retain(|x| *x != 0);
result
}
参考链接
其它算法
判断n是否为完全平方数
牛顿法
fn is_perfect_square(num:usize) ->bool {
let mut x = num;
while (x * x) > num {
x = (x + num / x)/2;
}
return x * x == num;
}
参考链接
最大公约数 & 最小公倍数
fn gcd(a: i64, b: i64) -> i64 { if b == 0 { a } else { gcd(b, a % b)} }
fn lcm(a: i64, b: i64) -> i64 { a / gcd(a, b) * b }