How do you find multiplicity of a prime factor in a prime factorization of number?

时间:2015-11-12 10:44:22

标签: c++ c

I have to find multiplicity of smallest prime factor in all numbers till 10^7.I am using Sieve of Eratosthenes to find all the prime numbers. And there in a seperate array phi i am storing smallest prime factors of composite numbers.Here is my code for that

 for(ull i=2;i<=m;i++)
{
    if (check[i])
    {
         uncheck[i]=true;
        for (ull k=i*i; k<=n; k+=i)
         {
           if(check[k]==true)
           phi[k]=g;
           check[k]=false;
         }  
    }

}

Now i am running a loop till n and using a loop inside it to calculate it. Here is code for that

 for(ull i=4;i<=n;i++)
{

    if(check[i]==false)
    {   
        ull count=0; 
        ull l=i;
         ull r=phi[i];
         while(l%r==0)
         {
            l=l/r;
            count++;
         }               
        cout<<count<<'\n';
    }


}

Is there any faster way to compute this?

5 个答案:

答案 0 :(得分:5)

Absolutely, you can do this without a loop.

c is probably at most 64 bits. It cannot contain any factor other than 1 more than 63 times. So instead of a loop, you write 63 nested if-statements.

For the case j == 2 your compiler may have some intrinsic functions that count trailing zero bits. If that is the case, then you handle that case separately and you need only 40 if's, because 3^41 > 2^64.

答案 1 :(得分:1)

If you want to evaluate n such that jn = c, then recast the problem to

n = log(c) / log(j).

If n is an integer then your problem is solved.

Of course you need to consider floating point precision here; n might not be an exact integer, but close to one.

答案 2 :(得分:0)

One alternative option, though not necessarily the most efficient, is to write a simple recursive function, such as this, assuming you are dealing with ints:

int recurseSubtract(int c, int j, int count){
  if ((c==j)) {
    return count + 1;
  } else {
     c = c-j;
     subtract(c, j, count++);
  }
}

int count = recurseSubtract(c,j,0);

However, see here for the pros and cons of loops vs. recursion.

答案 3 :(得分:0)

由于您要求“最小素数因子的多重性”,您可以轻松地使用相同的筛选方法来获得多样性,因为您习惯于获得最小因子。

 for(ull i=2;i<=m;i++)
{
    if (check[i])
    {
        uncheck[i]=true;  // WHY??
        ull k=i*i;
        for (ull q=i; q<maxq; k=(q*=i))
        for ( ; k<=n; k+=q)
         {
           if(check[k]==true)
               phi[k]=g;  // I copied 'g' from you, but didn't you mean 'i'?
           if ( phi[k]==g )
               count[k]++;
           check[k]=false;
         }  
    }

}

如果您想要做得更好一点,则需要phi[k]==g的步骤和check[k]访问中的一些冗余,因为q值是按正序处理的。反向使用q会更快。由于q只能在正向序列中轻松计算,并且每个i的q值相当少,因此向后处理q的最简单方法是将q上的循环转换为递归函数(在进入和处理的过程中计算q)在递归调用之后。)

答案 4 :(得分:0)

我发现了一个简单的规则,但无法用语言来描述。这是另一个计算素数的代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double f_power(double val, int exp);
int main(int argc,char* argv[]) {

    int p[2];
    int ctr = 0;
    int ctr2 = 0;
    int it_m = 0;
    int it_1 = 0;
    int it_2 = 0;
    int it_c = 0;


    int index = 3;
    srand(time(NULL));
    double t = clock();
    double s = clock();
    int prime = 2;
    FILE *file;
    file = fopen("ly_prime.txt", "w");
    //f_power(2.0, 57885161)
    for (it_m = 2; it_m <= 2000; it_m++) {
        for (it_1 = it_m, ctr2 = 0, it_c = it_m; it_1 >= 2; it_1--) {
            for (it_2 = it_1; it_2 >= 2; it_2--) {
                if (it_1 * it_2 - it_c == 0) {
                p[ctr % 2] = it_c;
                if (ctr >= 1 && p[ctr % 2] - p[(ctr - 1) % 2] == 2) {
                    //prime[0] = (p[ctr % 2] - 1);
                    prime = (p[ctr % 2] - 1);
                    fprintf(stdout, "|%d _ i: %d _ %d\n", isPrime(prime),index, prime);
                    index++; 
                }
                ctr++;
                }
            }
        }
    }
    t = clock() - t;
    fprintf(file, "|%d_ %d_ %d ", prime, index - 2, ctr);

}
double f_power(double val, int exp) {
int i = 0;
double help = val;
for(i = 1; i < exp; i++) {
    val *= help;
}
return val;
}
int isPrime(int number)
{
        int i = 2;
    for(i=2; i < number; i++)
    {
            int leftOver=(number % i);

            if (leftOver==0)
            {
                    return 1;
                    break;
            }

    }
            return 0;
}

也许可以帮助您理解,最好的问候