C++ 实现求小于n的最大素数的实例

C++ 实现求小于n的最大素数的实例

枚举就是基于已有知识镜像答案猜测的一种问题求解策略

问题:求小于n的最大素数

分析:

找不到一个数学公式,使得根据N就可以计算出这个素数

    我们思考:

N-1是素数么?N-2是素数吗?...    
    所以我们就是判断N-K是否为素数:
    N-K是素数的充分必要条件:N-K不能被[2,n-k)中任何一个整除    
    判断N-K是否为素数的问题可以转化为:
    求小于N-K的全部素数(求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除”,而不是整数)
    不能被[2,n)中任意一个素数整除的数一定是素数,因为那些整数都是以素数为因子的,
    所以没必要检测所有整数,检测所有素数就ok了

解决方法:

2是素数,记为PRIM 0

根据PRIM 0,PRIM 1,...PRIM K,寻找比PRIM K大的最小素数PRIM K+1(这里是根据素数找素数)

如果PRIM K+1大于N,则PRIM K是我们需要找的素数,否则继续寻找

    枚举:

从可能的集合中一一列举各元素
        根据所知道的知识,给一个猜测的答案
        比如:2是素数,那2是本问题的解么

枚举算法:

对问题可能解集合的每一项:
            根据问题给定的检验条件判断哪些是成立的
            使条件成立的即为问题的解

   枚举过程:

判断猜测答案是否正确
            2是小于N的最大素数么?
        进行新的猜测:

有两个关键因素要注意:

1. 猜测的结果必须是前面的猜测中没有出现过的。每次猜测的素数一定要比已经找到的素数大
                2. 猜测的过程中要及早排除错误的答案。比如:除2之外,只有奇数才可能是素数

    枚举过程中需要考虑的问题:

1. 给出解空间,建立简介的数学模型
            可能的情况是什么?
            模型中变量数尽可能的少(使规模尽量小),他们之间相互独立
                求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除”
                而不是“n不能被[2,n)中任意一个整数整除”

2. 减少搜索的空间

利用知识缩小模型中各变量的取值范围,避免不必要的计算
            比如:较少代码中循环体执行的次数
                除2之外,只有奇数才可能是素数,{2,2*i+1|1<=i,2*i+1<n}

3. 采用合适的搜索顺序

搜索空间的遍历顺序要与模型中条件表达式一致
            例如:对{2,2*i+1|1<=i,2*i+1<n},按照从小到大的顺序

  枚举关键字(枚举核心):

减少规模

实例代码:

#include <iostream>
using namespace std;
int prim[50000];//用来存所有素数
int primNum=0;//用来记录 prim数组中已经存入的素数的数量
int times=0; //用于记录求解问题的总共判断次数
int primLessN(int n);
int primLessN_2(int n);
bool isPrimMothed(int n); //判断一个数是否为素数 

/*
  方法一:由前往后用素数判断的枚举法:
  求“小于N的最大素数”中的条件是“n不能被[2,n)中任意一个素数整除”,而不是整数

  当n=10 0000时,
  ans=99991
  times=4626 4478次
  primNum=9592 

  我每一个素数被判断出来,都要遍历一下之前的素数表
  而判断10 0000的时候,外层循环走了50000,里层每一个素数就是一次之前素数表的遍历
  50000*(1+2+3+...+9592)=50000* 4600 8082
  前面那个数没有50000,还要减去那些非素数
  从 50000* 4600 8082可以看出,主要是之前那些素数花的时间,非素数几乎没花时间
  非素数= 4626 4478-4600 8082= 25 6450
  只有25万,虽然还是要比下面多很多,因为是从前往后比较的
*/
int primLessN(int n)
{
  prim[0]=2; //2是最小的素数
  primNum++;
  for(int i=3;i<n;i+=2){
    bool isPrim=1; //isPrim用来判断一个数是否为素数
    for(int j=0;j<primNum;j++){
      times++;
      if(i%prim[j]==0){
        isPrim=0;
        break; //没加break之前, 当n=10 0000时,times=2 5239 6936次 (2.5亿) ,加了之后times=4626 4478次 (4.5千万次)
      }

    }
    if(isPrim) prim[primNum++]=i;//如果是素数,则存入prim素数数组
  }
  return prim[primNum-1];
} 

/*
  方法二: 由后往前的整数枚举法
  而且方法二的空间消耗也少 

  当n=10 0000时,
  ans=99991
  times=346次 

  当n=100 0000时,用方法一的话,根本算不出来
  ans=99 9983
  times=1811次 

  当n=1 0000 0000(一亿)时,
  ans=9999 9989
  times=11314次 

  当n=10 0000 0000(十亿)时,
  ans=9 9999 9937
  times=52537次
*/
bool isPrimMothed(int n){
  bool isPrim=1; //isPrim用来判断一个数是否为素数
  if(n==2||n==3) return 1;
  for(int i=2;i*i<=n;i++){
    times++;
    if(n%i==0) return 0;
  }
  return 1;
} 

int primLessN_2(int n){
  for(int i=n;i>=2;i--){
    if(isPrimMothed(i)) return i;
  }
}
int main(){
  int n;
  scanf("%d",&n);
  //int ans=primLessN(n);
  int ans=primLessN_2(n);
  cout<<ans<<endl;
  printf("总判断次数times:%d\n",times);
  printf("总素数数primNum:%d\n",primNum);
  return 0;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • c++素数筛选法

    素数(又称质数):指在大于一的自然数中,只能被1和它自身整除的自然数: 素数筛选法是指一种非常规的素数判定方法,比较高效率: 原理:任何数的整数倍必定不是素数,大于二的偶数必定不是素数. 我们以找出100以内的素数为例,利用原理,我们可以首先排除偶数是素数,然后进一步判断奇数 实现将偶数标记为0,素数标记为1:(也可以用一个bool数组将偶数标记为false,奇数标记为true) 下面是全部代码 #include <iostream> #include <cmath> #defin

  • C++回文数及素数问题计算方法

    本文实例讲述了C++回文数及素数问题计算方法.分享给大家供大家参考,具体如下: /* * 作 者: 刘同宾 * 完成日期:2012 年 11 月 16 日 * 版 本 号:v1.0 * * 输入描述: 编制一个返回值为bool型的函数isPrimer(),用于判断参数是否为素数,isPalindrome()用于判断参数是否是回文数,调用函数回答以下问题(可以分别编制几个程序完成,也可以在一个main()函数中完成,输出时,用明显的提示语,说明正在完成哪个任务.) (1)输出10000以内的所有素

  • C++ 实现求小于n的最大素数的实例

    C++ 实现求小于n的最大素数的实例 枚举就是基于已有知识镜像答案猜测的一种问题求解策略 问题:求小于n的最大素数 分析: 找不到一个数学公式,使得根据N就可以计算出这个素数     我们思考: N-1是素数么?N-2是素数吗?...         所以我们就是判断N-K是否为素数:     N-K是素数的充分必要条件:N-K不能被[2,n-k)中任何一个整除         判断N-K是否为素数的问题可以转化为:     求小于N-K的全部素数(求"小于N的最大素数"中的条件是&q

  • Java实现求小于n的质数的3种方法

    质数概念 质数,又称素数,指在一个大于1的自然数中,除了1和此整数自身外,无法被其他自然数整除的数(也可定义为只有1和本身两个因数的数). 最小的素数是2,也是素数中唯一的偶数:其他素数都是奇数.质数有无限多个,所以不存在最大的质数. 一:根据定义去求解: 也是最笨的方式,效率比较低: package test.ms; public class FindPrime { // find the prime between 1 to 1000; public static void main(Str

  • Python实现求最大公约数及判断素数的方法

    本文实例讲述了Python实现求最大公约数及判断素数的方法.分享给大家供大家参考.具体实现方法如下: #!/usr/bin/env python def showMaxFactor(num): count = num / 2 while count > 1: if num % count == 0: print 'largest factor of %d is %d' % (num, count) break #break跳出时会跳出下面的else语句 count -= 1 else: prin

  • JS实现计算小于非负数n的素数的数量算法示例

    本文实例讲述了JS实现计算小于非负数n的素数的数量算法.分享给大家供大家参考,具体如下: 计算小于非负数n的素数的数量 例: 输入: 10 输出: 4 说明:有4个素数小于10,它们是2,3,5,7. JS算法示例: <script> var countPrimes = function(n) { let flagArray = [], result = 0; for(let i = 2; i < n; i++){ if(flagArray[i] === undefined){ flag

  • Python求区间正整数内所有素数之和的方法实例

    前言 Python的学习记录与分享--PTA程序设计类教学平台.如果你也正在学习关于此类的题目可以仔细阅读这篇文章,了解一下循环结构.素数的基本语法知识. 题目: 7-5就区间正整数内所有素数之和 (20分) [描述]求m-n以内所有素数之和并输出.‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬素数指从大于1,且仅能被1和自己整除的整数.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬

  • Python 判断是否为质数或素数的实例

    一个大于1的自然数,除了1和它本身外,不能被其他自然数(质数)整除(2, 3, 5, 7等),换句话说就是该数除了1和它本身以外不再有其他的因数. 首先我们来第一个传统的判断思路: def handlerNum(num): # 质数大于 1 if num > 1: # 查看是否有其他因子 for i in range(2, num//2+1): if (num % i) == 0: print(num,"不是质数") break else: print(num, "是质

  • java8 集合求差集、并集、交集的实例

    前言 java8里最大亮点是lambda,让我们用习惯C# linq的语法,也能眼前一亮.但是比起C#的语法糖还是差的很远. 差集.并集.交集 @Test public void test1(){ List<Integer> list1=new ArrayList<>(); list1.add(1); list1.add(2); list1.add(3); List<Integer> list2=new ArrayList<>(); list2.add(3)

  • python求前n个阶乘的和实例

    我就废话不多说了,还是直接看代码吧! i = int(input("input")) sum = 0 if i<1: exit() else: while i>0: b = 2 c = 1 while b<=i: c=b*c b=b+1 sum += c i = i-1 # print(c) print(sum) 补充知识:python 利用递归方法求解n的阶乘和 写程序算出n的阶乘的和 def fn(x): if x==1: return 1 def f(x): i

  • PHP求小于1000的所有水仙花数的代码

    水仙花数是一个n(>=3)位数字的数, 它等于每个数字的n次幂之和. 例如, 153是一个水仙花数, 153=1³+5³+3³. 编写程序, 求解小于1000的所有水仙花数. 复制代码 代码如下: <?php for($i=100;$i<1000;$i++){ $a=intval($i/100); $b=intval($i/10)%10; $c=$i%10; if(pow($a,3)+pow($b,3)+pow($c,3)==$i){ echo $i."\t"; }

  • Python实现高效求解素数代码实例

    素数是编程中经常需要用到的. 作为学习Python的示例,下面是一个高效求解一个范围内的素数的程序,不需要使用除法或者求模运算. #coding:utf-8 #设置python文件的编码为utf-8,这样就可以写入中文注释 def primeRange(n): myArray=[1 for x in range(n+1)] ##列表解析,生成长度为(n+1)的列表,每个数值都为1 myArray[0]=0 myArray[1]=0 startPos=2 while startPos <= n:

随机推荐