C++质数相关的算法操作:判断质数、分解质因数、筛质数(内附代码)

1. ​​​​​​质数的判定

算法过程:

  1. N小于2,返回false
  2. i从2枚举到 n / i,如果n % i == 0 说明有余数, 返回false
  3. 全都通过返回true。

代码:

bool is_prime(int n)
{
    if(n<=1) return false;
    for(int i=2; i <= n/i; i++)
    {
        if(n % i == 0) return false ;
    }
    return true;
}

2. 分解质因数

算法过程:

  1. 从2开始枚举所有的因数,到n / i
  2. 如果n % I == 0, 使用while循环将该质数除尽,并累加数量
  3. 如果最后n > 1,输出这个唯一一个大于√n的质因子。

代码:

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            int s = 0;
            while (x % i == 0) x /= i, s ++ ;
            cout << i << ' ' << s << endl;
        }
    if (x > 1) cout << x << ' ' << 1 << endl;
    cout << endl;
}

3. 筛质数(朴素筛法)

算法过程:

  1. i从2循环到n
  2. 如果该数是质数,从i+i到n筛掉所有该质数的合数
void get_primes()
{
    for(int i = 2; i <= n; i++)
    {
       if(!st[i])
       {
           p[cnt++] = i;
           for(int j = i + i; j <= n; j += i) st[j] = true;
       }
    }
}

4. 筛质数(线性筛法)

  1. I从2循环到n
  2. 如果是质数,加入到质数列表中
  3. 从小到大枚举所有质数到n / I, 筛掉primes[j] * i,当primes[j]是i的最小质因子时break。

成立的原理:

每个合数,均是由最小的质因子primes[j]筛掉的,理由如下:当pj 是i的最小质因数时break,保证pj 是pj * i的最小质因数;当未被break时,pj即小于i的最小质因子。综上全集,合数一定是被最小质因子pj筛掉的。又由于每个合数一定存在最小质因子,且当i枚举到I / pj的时候就被筛掉了,每个合数只被筛了一遍,所以是线性的。

代码:

void get_primes()
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i]) p[cnt++] = i;
        for(int j = 0; p[j] <= n / i; j++)
        {
            st[p[j] * i] = true;
            if(i % p[j] == 0) break;
        }
    }
}

代码模板转自:Acwing网站

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: #include <stdio.h> int main() { int n, i; printf("输入一个正整数: "); scanf("%d",&n); printf("分解质因数: "); for(i=2; i<=n; i++) { while(n%i == 0) { printf("%d ",i); n=n/i; } } printf("\n"); return 0; } ### 回答2: 要实现一个运行速度最快的分解质因数算法,可以使用Pollard Rho算法。这是一个基于随机性的质因数分解算法,其主要思想是通过不断迭代生成一个序列,其中的元素可能是合数,然后使用辗转相除法来判断是否找到一个质因数。 下面是使用C代码实现的简化版本: ``` #include <stdio.h> long long gcd(long long a, long long b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } long long pollardRho(long long n) { long long x = 2, y = 2, d = 1; while (d == 1) { x = (x * x + 1) % n; y = (y * y + 1) % n; y = (y * y + 1) % n; d = gcd((x - y + n) % n, n); } return d; } int main() { long long n; printf("请输入一个正整数:"); scanf("%lld", &n); printf("%lld的一个质因数是:%lld\n", n, pollardRho(n)); return 0; } ``` 该代码通过求解随机迭代序列的非平凡最大公约数来找到一个质因数。与传统的试除法相比,Pollard Rho算法在较大的数上运行速度更快。在实际使用时,可以进一步改进代码以提高效率,并处理特殊情况。 ### 回答3: 要编写一个运行速度最快的分解质因数算法,可以采用试除法的优化形式,又称为Pollard's rho算法。 首先,我们需要写一个用于检测一个数是否为素数的函数。可以使用试除法,从2到sqrt(n)逐个检查是否有因数。如果找到一个因数,说明n不是素数;如果没有找到因数,说明n是素数。 接下来,我们可以使用Pollard's rho算法分解质因数。这个算法的思想是利用了环的周期性来找到质因数。 具体步骤如下: 1. 定义一个函数f(x),表示f(x) = x^2 + 1。 2. 初始化x = 2和y = 2,计算f(x)和f(f(y))。 3. 利用欧几里得算法计算f(x)和f(f(y))的差值d。 4. 如果d是一个质数,则d即为n的一个质因数。 5. 如果d是合数,重复步骤2-4直到找到一个质因数。 通过不断重复步骤2-4,我们可以找到n的一个质因数。然后可以递归地对这个质因数进行分解,直到无法再分解为止。 通过这种方式,可以得到一个快速的质因数分解算法。当然,实现中还可以对代码进行优化,例如可以用位运算代替乘法和除法操作,以提高运行速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值