何为素数:
素数又称为质数,是指在大于1的自然数中,除了1和它本身以外不再有其他约数(因数)的自然数。
1.判断整数n是否为素数:
样例输入:
53
样例输出:
true
问题分析:
根据定义知,我们只要检查2~n-1的所有整数是否整除n就可以判定是否为素数。
如果d为n的约数,那么n/d也是约数。n和n/d之间的最小值,小于等于根号n。说白了,这个最小值的平方小于等于n。
对于上述,如果不懂的话,可以想一个简单的例子:对于20,其两个约数是4和5,两者之间4小,4小于等于根号20(4.472),并且4的平方小于20。
所以我们检查时,只需要从2~根号n,看两者之间有没有约数。如果没有就是素数。(或者从2的平方到n之间)
C++判断是否为素数:
bool is_prime(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return n!=1;
}
【注】:代码最后一行,也就是如果我们输入为1,同样返回false。
2.整数n的约数枚举:
样例输入:
40
样例输出:
1 40 2 20 4 10 5 8
如果了解如何判断整数是否为素数,那么这个问题就比较好解答。
C++代码:
vector<int> divisor(int n){
vector<int> res;
for(int i=1;i*i<=n;i++){
if(n%i==0){
res.push_back(i);
//如果i为约数,那么n/i同样为约数,如果两者不相等就放入容器中
if(i!=n/i) res.push_back(n/i);
}
}
return res;
}
其实和判断是否为素数流程一样,只不过在整除时,将约数放入容器。
3.将整数分解:
将整数分解为较小约数的乘积和。
样例输入:
40
样例输出:
2^3+5^1
C++代码:
map<int,int> prime_factor(int n){
map<int,int> res;
for(int i=2;i*i<=n;i++){
//n如果可以被整除,那么可以被整除几次
while(n%i==0){
++res[i];//整除一次,就+1
n/=i;//n的值改变
}
}
if(n!=1) res[n]=1;
return res;
}
上述三种算法的完整操作:
#include <iostream>
#include <vector>
#include <map>
using namespace std;
//是否为素数
bool is_prime(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0) return false;
}
return n!=1;
}
//约数枚举
vector<int> divisor(int n){
vector<int> res;
for(int i=1;i*i<=n;i++){
if(n%i==0){
res.push_back(i);
if(i!=n/i) res.push_back(n/i);
}
}
return res;
}
//整数分解
map<int,int> prime_factor(int n){
map<int,int> res;
for(int i=2;i*i<=n;i++){
while(n%i==0){
++res[i];
n/=i;
}
}
if(n!=1) res[n]=1;
return res;
}
int main(int argc, char** argv) {
int n;
scanf("%d",&n);
bool isprime=is_prime(n);
printf("是否为素数:\n");
cout<<boolalpha<<isprime<<endl;
vector<int> div=divisor(n);
printf("\n约束枚举:\n");
for(int i;i<div.size();i++){
printf("%d ",div[i]);
}
printf("\n");
map<int,int> factor=prime_factor(n);
map<int,int>::iterator ite;
printf("\n整数分解:\n");
for(ite=factor.begin();ite!=factor.end();++ite){
printf("%d^%d",ite->first,ite->second);
if(ite!=--factor.end()){
printf("+");
}
}
return 0;
}
样例输入和输出:
40
是否为素数:
false
约束枚举:
1 40 2 20 4 10 5 8
整数分解:
2^3+5^1