四胞胎素数
找出个位数分别是 1、3、7、9,且十位及更高位数字完全相同的质数
大于10之后的质数,个位数一定是[1,3,7,9]中的某一个
这类数的形式是:
10×a + d ,其中 a 是十位及以上组成的整数(a ≥ 1),d ∈ {1, 3, 7, 9},且四个数都必须是质数。
最终结果:
满足"个位数是 1、3、7、9,且前面数字相同"的质数组合有:
- 11, 13, 17, 19
- 101, 103, 107, 109
- 191, 193, 197, 199
这些是小于 200 内仅有的三组。
因个位数是奇数,因此 不用考虑除以2.个位数不是5,因此,也不用考虑除以5.
除数只用考虑 除以 3 和 7,11 开始的质数
C#示例程序:
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/*
* 找出个位数分别是 1、3、7、9,且十位及更高位数字完全相同的质数
大于10之后的质数,个位数一定是[1,3,7,9]中的某一个
这类数的形式是:
10×a + d,其中 a 是十位及以上组成的整数(a ≥ 1),d ∈ {1, 3, 7, 9},且四个数都必须是质数。
我们计算出 10~10000之间的连续质数序列
*/
namespace PrimeSerialDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("-------------------------------四胞胎素数-------------------------------");
Console.WriteLine("获取10~10000之内的连续质数【找出个位数分别是 1、3、7、9且十位及更高位数字完全相同的质数】");
GetPrimeQuadruplets();
Console.ReadKey();
}
/// <summary>
/// 获取 四胞胎素数
/// 获取10~10000之内的连续质数【找出个位数分别是 1、3、7、9且十位及更高位数字完全相同的质数】
/// </summary>
static async void GetPrimeQuadruplets()
{
Task task = Task.Run(() =>
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
int[] singleDigits = new int[4] { 1, 3, 7, 9 };//个位数是1,3,7,9
int sequence = 0;//第几组组合
for (int i = 10; i < 10000; i += 10)
{
int[] numbers = new int[4] { i + singleDigits[0], i + singleDigits[1], i + singleDigits[2], i + singleDigits[3] };
if (JudgeAllPrime(numbers))
{
sequence++;
Console.WriteLine($"当前第【{sequence}】组连续质数为【{string.Join(", ", numbers)}】");
}
}
stopwatch.Stop();
Console.WriteLine($"10~10000之内的四胞胎素数共有【{sequence}】组,耗时【{stopwatch.Elapsed.TotalSeconds}】秒");
});
await task;
}
/// <summary>
/// 使用埃拉托色尼筛法获取小于 n 的所有质数
/// </summary>
/// <param name="n">上限值(不包含)</param>
/// <returns>包含所有小于 n 的质数的列表</returns>
static List<int> GetPrimesLessThan(int n)
{
// 布尔数组,索引代表数字,值代表是否为质数
// 初始化为 true,假设所有数都是质数
bool[] isPrime = new bool[n];
for (int i = 2; i < n; i++)
{
isPrime[i] = true;
}
// 筛法核心逻辑
// 只需要检查到 sqrt(n)
for (int i = 2; i * i < n; i++)
{
if (isPrime[i])
{
// 如果 i 是质数,则将 i 的所有倍数标记为非质数
// 从 i*i 开始,因为更小的倍数已经被之前的质数标记过了
for (int j = i * i; j < n; j += i)
{
isPrime[j] = false;
}
}
}
// 收集结果
List<int> primes = new List<int>();
for (int i = 2; i < n; i++)
{
if (isPrime[i])
{
primes.Add(i);
}
}
return primes;
}
/// <summary>
/// 判断一个整数是否是质数
/// 大于10之后的质数,个位数一定是[1,3,7,9]中的某一个
/// </summary>
/// <param name="number">待判断的整数</param>
/// <returns>如果是质数返回true,否则返回false</returns>
static bool IsPrime(int number)
{
// 小于2的数不是质数
if (number < 2)
{
return false;
}
// 2和3是质数
if (number <= 3)
{
return true;
}
// 排除偶数和3的倍数,优化循环步长
if (number % 2 == 0 || number % 3 == 0)
{
return false;
}
// 只需检查到sqrt(number),且只检查6k±1形式的数
for (int i = 5; i * i <= number; i += 6)
{
if (number % i == 0 || number % (i + 2) == 0)
{
return false;
}
}
return true;
}
/// <summary>
/// 判断指定的数字集合是否全都为质数【素数】
/// </summary>
/// <param name="numbers"></param>
/// <returns></returns>
static bool JudgeAllPrime(int[] numbers)
{
for (int i = 0; i < numbers.Length; i++)
{
if (!IsPrime(numbers[i]))
{
return false;
}
}
return true;
}
}
}
运行如图:
