std :: map <int,int> increment </int,int>

时间:2013-12-25 08:26:31

标签: c++ map increment

我正在尝试编写一个返回给定数字的素数因子化的函数(作为解决项目euler问题#12的一部分)。计算素因子。我使用std::map。 代码如下:

#include "stdafx.h"
#include <iostream>
#include <map>
#include <algorithm>


bool IsPrime(unsigned int number)
{
    if (number < 1) return 0; // zero is not prime. For our purposes, one would be.
    for (unsigned int i = 2; i*i <= number; ++i)
    {
        if (number % i == 0)
            return false;
    }
    return true;
}


int divisors(unsigned int num)
{
    int orig_num = num;
    std::map <int, int> primefactors; 
    for(unsigned int i = 1; i <= num; ++i)
        if (num % i == 0 && IsPrime(i))
        {
            num /= i;
            ++primefactors[i];
            std::cout << primefactors[i] << "\t";
        }
    std::cout << orig_num << " = "; 
    for(auto& iter:primefactors)
         std::cout << iter.first <<  "^" << iter.second << " * ";
    return 0;   
}

int main()
{
    divisors(661500);
    return 0;
}

问题在于primefactors的所有计数都返回为1,尽管main中的数字被特别选择为素数乘以大于1的幂(661500 = 1 ^ 1 * 2 ^ 2 * 3 ^ 3 * 5 ^ 3 * 7 ^ 2)。 我的猜测是我正在增加错误。

1 个答案:

答案 0 :(得分:4)

每个素数只划分一次。但只要数字可被整除,你就应该继续除以素数:

for(unsigned int i = 2; i <= num; ++i)
        if (IsPrime(i))
        {
            while (num % i == 0) {
                num /= i;
                ++primefactors[i];
                std::cout << primefactors[i] << "\t";
            }
        }

实际上不需要IsPrime(i)条件:

for(unsigned int i = 2; i <= num; ++i)
    while (num % i == 0) {
        num /= i;
        ++primefactors[i];
        std::cout << primefactors[i] << "\t";
    }

证明:如果i不是素数,则条件num % i == 0意味着num可以被p的素因子i整除。但是p < i所以我们的循环必须在p之前的某个时间经过i。并且while循环将有效地删除pnum的所有出现。特别是在for到达i时,我们num不再能被p整除。矛盾。即如果满足num % i == 0,则在上面的循环中,i为素数。