如果一个n位的数字包含了1到n的每个数,那么这个数字叫pandigital number(没想好怎么翻译)如:2143十一个4位的pandigital number并且还是素数
求解最大的n位的pandigital prime
最初的时候我是打算写一个识别pandigital数的方法,然后迭代遍历是否为素数,这个函数不难写,但是判断效率太慢了,而且如果要遍历一个9位数,计算量非常大,故放弃此方法。后来感觉pandigital数应该不会很多,可以通过排列组合的方式构造一些出来,然后在这个小集合中再判断是否素数
use algorithms::math::is_prime::is_prime;
pub fn permutate(prefix: &str, s: &str, result: &mut Vec<String>) {
let n = s.len();
if n == 0 {
result.push(prefix.to_owned());
} else {
for i in 0..n {
let s1 = format!("{}{}", prefix.to_owned(), &s[i..=i].to_owned());
let s2 = format!("{}{}", s[0..i].to_owned(), s[i + 1..n].to_owned());
permutate(s1.as_str(), s2.as_str(), result);
}
}
}
pub fn largest_pandigital_prime() -> usize {
let mut ns = vec![];
permutate("", "1234567", &mut ns);
let mut largest = 0;
for val in &ns {
let num = val.parse::<usize>().unwrap();
if is_prime(num) && num > largest {
largest = num;
}
}
largest
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_permutate() {
let mut a = vec![];
permutate("", "1234", &mut a);
assert_eq!(24, a.len());
}
#[test]
fn test_largest_pandigital_prime() {
assert_eq!(7652413, largest_pandigital_prime());
}
}
有2个核心方法,一个是构造字符串全排列的方法,另一个用来判断并且返回最大符合要求的数字。构造全排列的方法很有意思,用了循环加递归,就是说对于一个字符串,提取出其中一个字符,放到首位,然后递归处理剩下的字符,很巧妙的办法,因为我测试了8位9位数字没符合条件的所以为了简便就写死只算7位数的