简体   繁体   English

您如何在数的素数分解中找到素数的多重性?

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

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. 我必须找到所有素数最小的素数直到10 ^ 7的多重性。我正在使用Eratosthenes筛子来查找所有素数。 And there in a seperate array phi i am storing smallest prime factors of composite numbers.Here is my code for that 在一个单独的数组phi中,我存储了最小的复合数素数。这是我的代码

 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. 现在我正在运行一个循环,直到n并在其中使用循环来计算它。 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? 有没有更快的方法来计算呢?

Absolutely, you can do this without a loop. 绝对可以,您无需循环即可执行此操作。

c is probably at most 64 bits. c最多为64位。 It cannot contain any factor other than 1 more than 63 times. 除1之外的其他任何因素都不能超过63次。 So instead of a loop, you write 63 nested if-statements. 因此,您编写了63个嵌套的if语句,而不是循环。

For the case j == 2 your compiler may have some intrinsic functions that count trailing zero bits. 对于j == 2的情况,您的编译器可能具有一些内在函数,它们会计算结尾的零位。 If that is the case, then you handle that case separately and you need only 40 if's, because 3^41 > 2^64. 如果真是这样,那么您将单独处理该情况,并且仅需要40个if,因为3 ^ 41> 2 ^ 64。

If you want to evaluate n such that j n = c, then recast the problem to 如果要评估n使得j n = c,则将问题重铸为

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

If n is an integer then your problem is solved. 如果n是整数,那么您的问题已解决。

Of course you need to consider floating point precision here; 当然,您需要在此处考虑浮点精度; n might not be an exact integer, but close to one. n可能不是精确的整数,但接近一个整数。

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:

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. 但是,请参见此处 ,了解循环与递归的优缺点。

Since you asked for the "multiplicity of smallest prime factor" you could easily use the same sieve approach to get multiplicity as you used to get the smallest factor. 由于您要求“ 最小质数的倍数”,因此您可以轻松地使用与获得最小因数相同的筛分方法来获得多重性。

 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;
         }  
    }

}

If you want to do a little better than that, the step of phi[k]==g and the some of the redundancy in check[k] access are needed only because q values are processed in forward sequence. 如果您想做得更好,则仅因为q值按正向顺序处理,才需要phi[k]==g的步骤以及check[k]访问中的一些冗余。 It would be faster to work with q in reverse. 反向使用q会更快。 Since q's are only easily computed in forward sequence and there are fairly few q's per i , the easiest way to process q backward would be to convert the loop over q into a recursive function (compute q on the way in and process it after the recursive call). 由于q只能按正向顺序轻松计算,并且每个i几乎不存在q,因此向后处理q的最简单方法是将q上的循环转换为递归函数(在递归的过程中计算q并在递归后对其进行处理呼叫)。

I found one simple rule but can not really describe in words. 我发现了一个简单的规则,但无法用语言描述。 Here is another code calculating primenumbers 这是另一个计算素数的代码

#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;
}

perhaps it helps understanding, best regards 也许这有助于理解,最好的问候

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM