实用算法实践-第 28 篇 素数判别

本文探讨了在素数判别中如何处理大数问题,分析了朴素算法的局限性,并介绍了概率算法Miller-Rabin。针对可能的死循环,提到了Pollard的rho算法。文章还指出,程序在实际运行时需要考虑语言选择和优化问题,以避免溢出和提高效率。
摘要由CSDN通过智能技术生成

28.1    朴素的素数判别

bool isPrime(__long n)
{
     //简单的判断素数的确定性算法
     __long i;
     if(n == 2|| n == 3)
         return true;
     if(n % 2 ==0)
         return false;
     for(i = 3;i < (__long)sqrt((double)n) + 1; i += 2){
         if(n %i == 0)
              returnfalse;
     }
     return true;
}
int prime(int n)
{
     int i;
     for(i=2;i*i<=n;i++)
         if(n%i==0)
              return0;
         return1;
}

28.2    素数筛选

void Prime() {
     memset(a, 0, n*sizeof(a[0]));
     int num =0, i, j;
     for(i = 2;i < n; ++i) {
          if(!(a[i]))
         {
              p[num++] = i;
         }
         for(j =0; (j<num && i*p[j]<n); j++){
              a[i*p[j]] = 1;
              if(!(i%p[j]))
              {
                   break;
              }
         }
     }
}

28.3    Miller-Rabin随机性素数测试方法

28.3.1   实例

PKU JudgeOnline, 1811, Prime Test.

28.3.2   问题描述

判断一个数N (2 < N < 254)是不是素数,是素数就输出 “Prim”,否则输出其最小的因子。

28.3.3   分析

这个题目考察的问题相当多,可以分为大素数的判别法、大数的分解两个问题。其中又牵涉到最大公约数的辗转相除求法(欧几里德算法)、模运算的性质(方幂模、模乘的实现)等。

这里N选取的范围恰到好处。输入的数不是很大,故此可以用__int64类型进行加、减、除、模运算。但是又要注意不能进行乘法运算,否则会溢出。

使用朴素的素数判别显然是不行的。这里需要使用概率算法:Miller-Rabin算法。其中Miller-Rabin需要求积的模和求乘方的模,这些都可以根据模的性质分解,使得计算不会溢出。

在完成素数判别之后,需要采用Pollard的rho启发式随机算法进行素数分解。该算法可能造成死循环。虽然死循环的可能性并不大,不幸碰到了就多提交几次。</

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值