题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质数的因子(如180的质数因子为2 2 3 3 5 ),最后一个数后面也要有空格。
输入描述:
输入一个long型整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
输入例子:
180
输出例子:
2 2 3 3 5
解题思路
首先根据long型整数num,产生一个素数表,表中的素数不超过sqrt(num),并且从小到大排列。因为超过sqrt(num)的素数最多只能有一个,所以可以单独判断这种情况,这样可以大大减小计算量。
根据这个素数表,判断num能否整除表中的各个素数。需要注意的是,num可以有多个同样的素数因子。当num不超过1或者素数表中元素都已经遍历过了,判断此时的num是否是素数,如果是,则表明有一个超过sqrt(num)的素数。
素性检验有多种方法,我这里用的是最简单的一种。
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> getResult(long num); //返回long型整数的所有质因子
void print(const vector<string>& vecStr); //按规定格式打印结果
vector<long> primeTable(long num); //产生小于等于sqrt(num)的质数表
bool isPrime(long num); //判断是否是质数
string DecToString(long num); //将long型整数转化为字符串
int main()
{
long num;
cin >> num;
vector<string> vecStr = getResult(num); //返回long型整数的所有质因子
print(vecStr); //按规定格式打印结果
return 0;
}
vector<string> getResult(long num) //返回long型整数的所有质因子
{
vector<long> vec = primeTable(num); //产生小于等于sqrt(num)的质数表
int i = 0;
vector<string> vecStr;
while (num > 1 && i < vec.size())
{
while (num > 1 && num % vec[i] == 0) //能整除质数vec[i]
{
vecStr.push_back(DecToString(vec[i]));
num /= vec[i];
}
++i;
}
if (isPrime(num)) //可能还有一个大于sqrt(num)的质数
{
vecStr.push_back(DecToString(num));
}
return vecStr;
}
void print(const vector<string>& vecStr) //按规定格式打印结果
{
for (string str : vecStr)
cout << str << " ";
cout << endl;
}
vector<long> primeTable(long num) //产生小于等于sqrt(num)的质数表
{
vector<long> vec;
for (long i = 2; i * i <= num; ++i)
{
if (isPrime(i))
vec.push_back(i);
}
return vec;
}
bool isPrime(long num) //判断是否是质数
{
if (num < 2)
return 0;
for (long i = 2; i * i <= num; ++i)
{
if (num % i == 0)
return 0;
}
return 1;
}
string DecToString(long num) //将long型整数转化为字符串
{
string str;
while (num > 0)
{
str = static_cast<char>(num % 10 + '0') + str;
num /= 10;
}
return str;
}