数学问题(五)——分解质因数

方法

  • 要求质因数,那么先要有质因数,所以可以先采用筛法获取素数数组,可参考:数学问题(四)——素数
  • 最简单的就是依次进行试除,如果可以整除则记录该因数

代码

//简单的记录该整数有多少个质因数
//prime是通过筛法得到的升序
int answer = 0;
for (int i = 0; i < prime.size() && prime[i] < n; i++)
{
    int factor = prime[i];
    while (n % factor == 0)
    {
        n /= factor;
        answer++;
    }
}
//最后一次prime[i] == n不会进入循环,所以要补上一
if (n > 1)
{
    answer++;
}

另外,在做这道题时,想如何存储所有数的质因数,写了如下代码(代码没有经过优化——其实没想到咋优化):

#define MAX 1001
map<int, int> Factors[MAX];
/*
修改筛法中素数的判断条件,map.size()==0说明就是素数
此外在初始化非素数的因数时,只进行一次,防止某个数被多次初始化,使得因数被过多记录
*/
void initial()
{
    for (int i = 2; i < MAX; i++)
    {
        if (Factors[i].size() == 0)
        {
            for (int j = i * i; j < MAX; j += i)
            {
                //对于非平方数来说,都只会有两个因数,且因数的幂都为1,
                //为了防止出现类似12,在i=2,i=3会被重复记录因数
                if (Factors[j].size() == 0)
                {
                    Factors[j][i]++;
                    Factors[j][j / i]++;
                }
            }
        }
    }
}
/*
分解质因数,思路时比较简单的,在初始化的过程中,每个非素数(非平方数)被初步分解为了x*y,
其中x已经是质数了,但是y不一定是质数,所以需要去查找y的因数有哪些,
因为是从小往大开始处理的,所以在替换y的时候,Factors[y]已经被完全分解.
至于时间复杂度,虽然是三重循环,但是第二层和第三层的遍历次数是小于sqrt(n),
因为n的质数的因数个数必然是小于等于sqrt(n).
虽然大部分的数的因数个数是小于sqrt(n),但是在初始化的过程中会增加可被分解的因数,
所以总体而言时间复杂度应该为O(n^2)
*/
void decompose()
{
    // 8是第一个需要处理的数
    for (int i = 8; i < MAX; i++)
    {
        for (auto &it : Factors[i])
        {
            // 该因数不是素数,需要遍历该因数的factors,替换该因数
            if (Factors[it.first].size() != 0)
            {
                it.second = 0; //就是从1变为0
                // 遍历该因数的factors
                for (auto &it2 : Factors[it.first])
                    // 因为在构造过程中,除平方数外,因数的幂都为1
                    Factors[i][it2.first] += it2.second;
            }
            //说明该因数已经是素数,不需要再进行分解
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值