素数求解的N种境界【转载】

素数求解的N种境界

    <div id="blogColumnPayAdvert">
        <div class="column-group">
            <div class="column-group-item column-group0 column-group-item-one">
                <div class="item-l">
                    <a class="item-target" href="https://blog.csdn.net/m0_66769266/category_11823443.html" target="_blank" title="典型例题" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.6332&quot;}">
                        <img class="item-target" src="https://img-blog.csdnimg.cn/6494da2886c040a884a2a451dcf8dbcc.png?x-oss-process=image/resize,m_fixed,h_224,w_224" alt="">
                        <span class="title item-target">
                            <span>
                            <span class="tit">典型例题</span>
                                <span class="dec">专栏收录该内容</span>
                            </span>
                        </span>
                    </a>
                </div>
                <div class="item-m">
                    <span>25 篇文章</span>
                    <span>16 订阅</span>
                </div>
                <div class="item-r">
                        <a class="item-target article-column-bt articleColumnFreeBt" data-id="11823443">订阅专栏</a>
                </div>
            </div>
        </div>
    </div>
<article class="baidu_pl">
    <div id="article_content" class="article_content clearfix">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/kdoc_html_views-51db9abdb7.css">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-6e43165c0a.css">
            <div id="content_views" class="markdown_views prism-tomorrow-night">
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                <p><img src="https://img-blog.csdnimg.cn/ec70c20728b74862bf38b2b8225c79b2.gif" alt="在这里插入图片描述"></p> 
本期介绍🍖

主要介绍:如何快速筛查素数的方法,详细讲解了试除法筛选法的N种境界👀。


目录🍖

前言🍖

  质数prime number)又称素数。一个大于1的自然数,除了1和它本身外,不能被其他自然数整除的数被称为素数(换句话说就是该数除了1和它本身以外不再有其他的因数)。现在有一个题目:请编写代码找出1——120之间的素数。那我们该如何编写关于这道题的较优代码呢?下面我会介绍两种类型的算法的代码,第一种为“试除法”,第二种为“筛选法”。


试除法🍖

  那什么是试除法呢?通过不断试除1和本身之外的自然数来判断该数是否为素数的方法称为试除法只要有一个自然是能够整除该数,则其就不是素数;若一个都不能整除该数,则其就是素数)。

境界1(试除从 2—(n-1) )🍖

  该方法就是循环遍历所有情况,效率很差。

#include<stdio.h>
int main()
{
	int i = 0;
	int count1 = 0;//循环的次数
	int count2 = 0;//素数的个数
	printf("1——120之间素数为:\n");
	for (i = 2; i <= 120; i++)
	{
		int j = 0;
		for (j = 2; j < i; j++)//试除除了1和它本身之外所有的数
		{
			count1++;
			if (i % j == 0)
			{
				break;
			}
		}
		if (j >= i)//若一个试除数都无法整除该数,则说明该数为素数
		{
			printf("%d ", i);
			count2++;
		}
	}
	printf("\n循环的次数为:%d", count1);
	printf("\n素数的个数为:%d",count2);
	return 0;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里插入图片描述


境界2(排除2的倍数的合数)🍖

  该方法还是和境界1一样是通过循环遍历所有情况达到目的地,其本质并没有发生任何变化,仅仅是稍微优化了一下下,几乎可以说是可有可无,所以该程序执行效率仍然差。

#include<stdio.h>
int main()
{
	int i = 0;
	int count1 = 0;//循环的次数
	int count2 = 0;//素数的个数
	printf("1——120之间素数为:\n");
	printf("%d ", 2);//不能忘记2也是素数
	count2++;
	for (i = 3; i <= 120; i+=2)//省略掉2的倍数的合数
	{
		int j = 0;
		for (j = 2; j < i; j++)//试除除了1和它本身之外所有的数
		{
			count1++;
			if (i % j == 0)
			{
				break;
			}
		}
		if (j >= i)//若一个试除数都无法整除该数,则说明该数为素数
		{
			printf("%d ", i);
			count2++;
		}
	}
	printf("\n循环的次数为:%d", count1);
	printf("\n素数的个数为:%d",count2);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在这里插入图片描述


境界3(试除从 2—sprt(n) )🍖

  该方法是通过试除从 2—sprt(n) 之间的所有数来判断是否为素数的,那为什么是 2—sprt(n) 这个范围呢?因为若这个数它不是素数必然可以进行因式分解,分解成两个因数相乘;既然这两个因数都可以用来判断是否为素数,那我们为什么要判断它两遍呢,一遍不就足够了?那该如何实现呢?
  如果你多因式分解几组自然数,你会发现分解出来的两个因数必然是一大一小且都相互趋近于被分解的那个数n的算数平方根。所以我们发现第1个因数的范围必然是在 2——sprt(n) 之间,而又由于我们只需要知道其中的一个因数就可以判断是否为素数,故试除的范围就可以定在 2——sprt(n) 之间了,这样我们就可以省略 sprt(n)——(n-1) 之间的试除,这真的是大大优化了境界1时的代码呀!!!

#include<stdio.h>
#include<math.h>
int main()
{
	int i = 0;
	int count1 = 0;//循环的次数
	int count2 = 0;//素数的个数
	printf("1——120之间素数为:\n");
	for (i = 2; i <= 120; i++)
	{
		int j = 0;
		for (j = 2; j <= sqrt(i); j++)//试除除了2——sqrt(i)之间的数
		{
			count1++;
			if (i % j == 0)
			{
				break;
			}
		}
		if (j > sqrt(i))//若一个试除数都无法整除该数,则说明该数为素数
		{
			printf("%d ", i);
			count2++;
		}
	}
	printf("\n循环的次数为:%d", count1);
	printf("\n素数的个数为:%d", count2);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在这里插入图片描述


筛选法🍖

  筛选法的由来可以追溯到古希腊时期,那时有个人叫埃拉托斯特尼,他发现可以通过在涂蜡的木板记下数字,接着在蜡上以记一个点来作为删去一个数字,然后从最小的质数开始一个接着一个的划掉这些质数的倍数的方法来实现求质数最后那些没被点标记的数就是质数了)。质数查找完成后,这有着密密麻麻小点的涂蜡板看上去就像一个筛子,所以就把着这种方法叫做:“埃拉托斯特尼筛选”,简称:筛选法
  从上面我们可以看出筛选法试除法其实有着本质上的区别,试除法是判断每一个数是不是素数来达到目的;而筛选法不是如此,筛选法是将不是素数的数全部去除,然后得到余下的数来达到目的。那该如何实现这个代码呢?看下去。

境界1(基础)🍖

  首先1不是质数也不是合数,所以要划去;接着2是公认最小的质数,所以要保留下来,再把所有2的倍数去掉;然后接下来遇到的第一数不会是2的倍数,所以它必然只可能被1和他自身整除,为素数,而2后面第一个没有被划去的数是3,所以要保留素数3,再把所有3的倍数去掉;接着往复之前的判断,剩下的那些大于3的数里面,最小的是5,所以5也是质数……
  上述过程不断重复,就可以把某个范围内的合数全都除去(就像被筛子筛掉一样),剩下的就是质数了。如果理解还不怎么清晰,我这有幅动图其能够直观地体现出筛法的工作过程,如下所示:

在这里插入图片描述

#include<stdio.h>
#include<stdbool.h>
#define NUM 200
int main()
{
	//建立一个bool类型的数组,用来存放该数组下标所对应的数是否为素数;是素数则存储true,否则存储false。
	bool is_prime[NUM] = { 0 };
	int i = 0;
	int count1 = 0;//循环总次数
	int count2 = 0;//素数的个数
	//初始化bool数组
	for (i = 0; i < NUM; i++)
	{
		is_prime[i] = true;
	}
	printf("1——120之间素数为:\n");
	//排查掉不是素数的数,并输出素数
	for (i = 2; i <= 120; i++)
	{
		if (is_prime[i])
		{
			int j = 0;
			count2++;
			printf("%d ", i);
			for (j = i + i; j <= 120; j += i)//从i+i开始筛i的倍数
			{
				is_prime[j] = false;
				count1++;
			}
		}
	}
	printf("\n循环总次数:%d", count1);
	printf("\n素数的个数:%d", count2);
	return 0;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述


境界2(优化)🍖

  其实上面这个程序还可以优化一下,不知道你有没有发现有一些数字我们会重复筛查好多次。就譬如数字6,我在筛查2的倍数时已经把它筛了一次,可在筛查3的倍数时仍然会重复筛,但其实筛一次就够了。所以只要我们能实现每个数只筛一次,就能节约一定的时间,这样程序就可以得到优化。
  那该如何做呢?我们发现,当 i=2 时,我们只需从 2 * 2 = 4 开始筛2的倍数;当 i=3 时,其实我们只需从3 * 3 = 9开始筛3的倍数(优化前的代码是从3+3开始筛的,因为前面我已经把2的倍数都筛了一遍,3+3自然也被筛了,所以没有必要再筛一次,那就往后看嘛从 3+3+3 开始筛);当 i=5时 ,我们发现只有当 5+5+5+5+5 的时候(即:5 * 5 = 25)才没有被之前的数筛过,所以从这开始筛5的倍数。总结一下,在筛一个数的倍数时,只要在该数的二次方那里开始筛它的倍数即可实现每个数只筛一次。

#include<stdio.h>
#include<stdbool.h>
#define NUM 200
int main()
{
	//建立一个bool类型的数组,用来存放该数组下标所对应的数是否为素数;是素数则存储true,否则存储false。
	bool is_prime[NUM] = { 0 };
	int i = 0;
	int count1 = 0;//循环总次数
	int count2 = 0;//素数的个数
	//初始化bool数组
	for (i = 0; i < NUM; i++)
	{
		is_prime[i] = true;
	}
	printf("1——120之间素数为:\n");
	//排查掉不是素数的数,并输出素数
	for (i = 2; i <= 120; i++)
	{
		if (is_prime[i])
		{
			int j = 0;
			count2++;
			printf("%d ", i);
			for (j = i * i; j <= 120; j += i)//从i*i开始筛i的倍数
			{
				is_prime[j] = false;
				count1++;
			}
		}
	}
	printf("\n循环总次数:%d", count1);
	printf("\n素数的个数:%d", count2);
	return 0;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述


总结🍖

  你别看试除法的境界3的循环次数和筛选法的循环次数也就差一半,就认为筛选法的效率也就比试除法快一倍。若我们把求素数的范围提到1000以内,筛选法的循环次数为:1411,而试除法的执行次数却是:5228。所以从这可以看出,求素数的范围越大就越能体现试除法的优越性。上面这些就是我今天想向大家分享的素数求解的N种境界!


在这里插入图片描述

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。

文章知识点与官方知识档案匹配,可进一步学习相关知识
C技能树首页概览 115311 人正在系统学习中
  • 48
    点赞
  • 77
    收藏
  • 打赏
    打赏
  • 27
    评论
C语言素数 求解的N 境界
08-27 4944
试除法 试除法就是要判断一个数x是否为 素数,就不断尝试小于x大于1的自然数,只要有一个能够整除,则x是合数,否则是 素数 1、 境界1(最差情况下) 判断x是否为 素数,从2一直尝试到x-1,这 方法效率很差

int main()
{
int i = 0;
int j = 0;
int count = 0;
for (i = 100; i <= 200; ++i)
{
for (…


求解 素数的筛选法
最新发布
关于 求解 素数的筛选法
学习篇 | 『 素数』查找方式总结_姜小逗的博客
1-1
特别地:数字 1 既不是 素数,也不是合数。 素数 求解的 N 境界 依次遍历 程序设计 #include <stdio.h> intmain() { inti =0; for(i =100; i <=200; i++) { //printf("%d", i); ...
2021-10-14_pheasent的博客
12-28
素数 求解的n 境界 8.判断9的个数 intmain()//判断9的个数{inti=1,count=0;for(;i<=100;i++){if(i%10==9){printf("%d ",i);count++;}if(i/10==9){printf("%d ",i);count++;}}printf("count=%d",count);re...
素数的判断方法
01-20 822
素数的判断方法
素数 求解的n 境界
01-27 926
第一 :基本方法 //4.判断i是否为 素数素数是指只能被1和其本身所整除的数字 //查找1-100之间的 素数 #include <math.h> #include <stdio.h>

int main()
{
int i = 0;
int count = 0;
for (i = 1; i <= 100; i++)
{
//试除法
int j = 0;
for (j = 2; j <= i; j++)
{
if (i%j == 0)



素数求法的N中 境界(以求100-200间的 素数为例)
06-30 268
前言

境界

1,试除法

2,i=a*b,a或b至少有一个数字<=sqrt(i)

3,偶数中找素数

4,除了2以外,所有可能的质因数都是奇数,所以,就先尝试2,然后从3开始,直到x/2的所有奇数。

前言

素数的定义:

1,质数又称素数,有无限个。一个大于1的自然数,除了1和它本身外,不能被其他自然数(质数)整除,否则称为合数。根据算术基本定理,每一个比1大的整数。

2,要么本身是一个质数,要么可以写成一系列质数的乘积;而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一…


求质数( 素数)算法,及算法优化
08-11 1万+
质数( 素数):只能被1和其本身整除的数字(其中1和0不属于质数) 接下来我们用多 方法求1000以内(包含1000)的质数数量,并且统计每 方法的循环次数 (如果只想知道速度快的方法可以直接看方法五) 方法一: 循环遍历所有情况 int count1 = 0;//质数个数 int count2 = 0;//循环次数 for(int i=2;i<=1000;i++) { int fla...
素数及其使用
03-19 1514
素数质数(prime number)又称 素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数。计算n以内的所有 素数的方法ref:http://www.cnblogs.com/hardsoftware/p/5935850.html ★题目  好,言归正传。下面俺就由浅入深,从各 角度来剖析这道题目的奥妙。   为了避免被人指责为”玩文字游戏”(有些同学自己审题
第二十二章: 求解 素数的N 方法
求解 素数的N 方法

一、质数和合数

质数:

质数又称**素数**。指在一个大于 1的自然数中,除了 1和此整数自身外,不能被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数即为质数。

最小的素数是 2, 它也是唯一的素数

从小到大的素数依次排列为∶ 2,3,5,7,11,13,17……

合数:

比 1大但不是素数的数称为合数(0 和1 既非素数也非合数)

最小的合数是 4。

从小到大的合数依次排列为∶4,6,8,9,10,12,14……

特别注意:

判断质.


素数 求解的五大 境界—— C语言
本篇博客介绍了 素数 求解的五大 境界
C语言-----求 素数的n 境界
// 素数的定义:质数(prime number)又称 素数,有无限个。一个大于1的自然数, //除了1和它本身外,不能被其他自然数(质数)整除, //换句话说就是该数除了1和它本身以外不再有其他的因数; //否则称为合数。根据算术基本定理,每一个比1大的整数, //要么本身是一个质数,要么可以写成一系列质数的乘积; //而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的。 //最小的质数是2

第一境界

#include<stdio.h>
int main() {//第一方法

素数的N 境界的实现
04-09 615
出处:program_think大神讲的《求质数算法的N 境界 (N &gt; 10)》 http://blog.csdn.net/program_think/article/details/7032600

需求1:/请实现一个函数,对于给定的整型参数 N,该函数能够把自然数中,小于 N 的质数,从小到大打印出来。
 比如,当 N = 10,则打印出
2 3 5 7
/

"◇境界1

在…


求数n的最大素因子是第几个 素数
问题描述 每个数都可以分解成质因数的乘积。现在求一个数n的最大素因子是 素数集合中的第几个 素数。n小于1000000。 解决方法 利用筛选法获得,具体可见求质数算法的N 境界- 试除法和初级筛法。 图解说明如下:

1、具体过程
对于1000000内的数字而言,利用筛选法计算其中素数,并标记出每个素数对应的位置信息。利用prime数组保存范围内的素数;利用position数组保存每个数所…


C语言求解 素数(质数)的N 境界
03-28 2768
★前言:

众所周知,不管是在学习、考试还是以后找工作中,对于求解素数的问题随处可见,而且还是一个重难点,为何要说是重难点呢?主要是因为对于不同的人往往会有不同做法,但大多数掌握的都是一些非常平庸的做法,完全没有技术含量。然而这对于我们这些技术人员无疑是一个BIG BUG。所以小编在此整理了一些求解套路,如有疑问,欢迎来扰。

★试除法:

首先要介绍的,当然非"试除法"莫属啦。考…


素数 求解的的几 简单方法
热门推荐
04-22 2万+
问题:打印出100到200之间的 素数方法一: 素数N就是除了1和它本身之外没有任何因子的数,所以要求 素数我们很容易想到从2到N-1去试除,如果能除尽说明它不是 素数,这个时候就接着判断下一个数也就是下面的这  上结果图方法二:方法一是可以做出来,但是要试的因子太多了有点。我们可以想到如果N有除了它本身之外的因子,那这个因子一定小于等于N/2(1*N=N,2*(N/2)=N,一个因子如果比N/2大了,那...
第一个竞赛题目( c语言部分)
大家注意到,函数的第一行是:“const double pi=acos(-1.0);”。 这里用到了const关键字来声明一个常数,acos是一个函数,其功能是求反余弦。acos(-1.0)就是求-1.0的反余弦,再赋值给double类型的常变量pi,经计算,acos(-1.0) 的值就是圆周率,因此你可以理解为acosta(-1.0)就是我们所说的pi。#include<stdio.h> #in
素数 求解的N 境界!!!
素数 求解的N 境界 境界1 境界2 境界3 境界4 下面以找出100~200 素数为例 境界1 正常筛选法 #include<stdio.h> int main() { int i; for (i = 100; i <= 200; i++) { int j ; for(j = 2 ; j < i; j++) { if (i % j == 0) break; } if (j == i) printf("%d ",i); } return 0; }
2021-08-26:为什么求 素数要用到2到sqrt(x)
为甚求 素数要用到2到sqrt(x)呢? 求 素数的python代码如下: import math

def prime(x):
if x == 1:
return False #输入的数是1 返回值是错误
n = int(math.sqrt(x)) #最短区间
for i in range(2,n):
if x % i ==0: # 余数是0就是有能被整除的数
return False
return


求质数算法的N 境界-试除法和初级筛法
求质数算法的N 境界-试除法和初级筛法 ★引子 前天,俺在《俺的招聘 经验[4]:通过笔试答题能看出啥?》一文,以&quot;求质数&quot;作为例子,介绍了一些考察应聘者的 经验。由于本文没有政治敏感内容,顺便就转贴到俺在CSDN的镜像博客。   昨天,某个CSDN网友在留言中写道: 老实说,这个程序并不好写,除非你背过这段代码 如果只在纸上让别人写程序,很多人都会出错 但是如果给一台电脑,大多数人都会把这个程序调试...

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:鲸 设计师:meimeiellie 返回首页

分类专栏

  • 编程项目 3篇
  • 典型例题 25篇
  • 排序算法 2篇

最新评论

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值