今天在知乎上看到一个问题,和n!的素数分解有关。发现初等数论里有关于n!的素数分解的结论。这个问题可以分为两个部分,第一部分是求出所有不超过n的素数,然后把这些素数存在一个数组里。第二部分是求出素数对应的幂,然后把这些幂存在另一个数组里。第二部分是很容易的,困难主要是在第一部分。
在第一部分中,问题也可以分为求出素数和存储素数这两个过程。判断一个数是否为素数的算法有两种,第一种是判断这个数能否被2到n/2的某个数整除,如果不能,则为素数。第二种是判断n是否能被某个不超过根号n的素数整除,如果不能,则为素数。从算法的复杂度来看,显然第二个看起来更好。对于存储素数这个过程,有动态数组和STL容器这两种方案。
至于编程语言,我打算用C++和matlab实现。
1、
下面是第一种C++实现。判断是否为素数的算法用的是第一种,存储用的是动态数组。
#include <iostream>
using namespace std;
int main()
{
int n;
cout << "Enter the number: ";
cin >> n; //输入n
if(n<2)
{
cout << "error" << endl;
return 0;
}
int *prime = new int[n]; //用于存储所有不超过n的素数
for(int i=0; i<n; i++)
prime[i] = 0;
int p = 2;
int count = 0;
bool isPrime;
while(p<=n)
{
isPrime = true;
for(int d=2; d<=p/2; d++)
{
if(p % d == 0)
{
isPrime = false;
break;
}
}
if(isPrime)
{
prime[count] = p;
count++;
}
p++;
}
/*
for(int j=0; j<n; j++)
cout << prime[j] << " ";
*/
int *countPrime = new int[count]; //用于存储素数的幂
for(int i=0; i<count; i++)
{
countPrime[i] = 0;
}
for(int i=0; i<count; i++)
{
int num = n/prime[i];
while(num != 0)
{
countPrime[i] += num;
num /= prime[i];
}
}
/*
for(int i=0; i<count; i++)
cout << countPrime[i] << " ";
*/
for(int i=0; i<count; i++)
{
cout << prime[i] << " " << countPrime[i] << endl;
}
return 0;
}
输出截图如下:
每行的第一个数字是素因子,第二个数字是对应的幂。
2、下面是第二种C++实现。判断是否为素数的算法用的是第二种,存储用的是STL容器。
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int main()
{
int n;
cout << "Enter the number: ";
cin >> n; //输入n
if(n<2)
{
cout << "error" << endl;
return 0;
}
vector<int> prime; //用于存储所有不超过n的素数
int p = 2;
int count = 0;
bool isPrime;
while(p<=n)
{
isPrime = true;
vector<int>::iterator p1;
for(p1=prime.begin(); p1!=prime.end()&&*p1<=sqrt(p);p1++)
{
if(p % *p1 == 0)
{
isPrime = false;
break;
}
}
if(isPrime)
{
prime.push_back(p);
count++;
}
p++;
}
int *countPrime = new int[count]; //用于存储素数的幂
for(int i=0; i<count; i++)
{
countPrime[i] = 0;
}
for(int i=0; i<count; i++)
{
int num = n/prime.at(i);
while(num != 0)
{
countPrime[i] += num;
num /= prime.at(i);
}
}
for(int i=0; i<count; i++)
{
cout << prime.at(i) << " " << countPrime[i] << endl;
}
delete [] countPrime;
return 0;
}
输出截图如下: