C语言 五种方法输出100以内的素数(质数) 源码

这篇具有很好参考价值的文章主要介绍了C语言 五种方法输出100以内的素数(质数) 源码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 文章来源地址https://www.toymoban.com/news/detail-448054.html

写在前面:

输出前20万个素数,对比简单遍历和欧拉筛选的运行时间。

简单遍历:

欧拉筛选:

一、简单遍历

二、遍历至该数的平方根      

三、用x/i来代替sqrt(x)

四、朴素筛法

五、埃式筛法

六、欧拉筛法        


 

写在前面:

输出前20万个素数,对比简单遍历和欧拉筛选的运行时间。

简单遍历:

#include <stdio.h>
#include <time.h>
clock_t start, stop;
double duration;

int main()
{
    int count = 0;
    start = clock(); /*开始计时*/
    int i, j;
    for (i = 2; i <= 200000; i++) {
        int isprime = 1;
        for (j = 2; j < i; j++) {
            if (i % j == 0) {
                isprime = 0;
                break;
            }
        }
        if (isprime == 1) {
            printf("%d\n", i);
            count++;
        }
    }
    printf("%d\n", count);
    stop = clock(); /*停止计时*/
    duration = ((double)(stop - start)) / CLK_TCK; /*计算运行时间*/
    printf("Running time: %lf seconds\n", duration); // 输出运行时间

    return 0;
}

C语言 五种方法输出100以内的素数(质数) 源码

3.243秒

欧拉筛选:

#include <stdio.h>
#include <stdbool.h>
#include <time.h>
clock_t start, stop;
double duration;

int main()
{
    int n = 200000;
    bool isPrime[200001];
    int prime[200001];
    int cnt = 0; //记录素数的个数
    for (int i = 2; i <= n; i++)
        isPrime[i] = true;

    for (int i = 2; i <= n; i++)
    {
        if (isPrime[i])
        {
            prime[cnt] = i; //将i加入素数数组
            cnt++;
        }
        for (int j = 0; j < cnt && i * prime[j] <= n; j++)
        {
            isPrime[i * prime[j]] = false; //将当前数与质因数的积标记为合数
            if (i % prime[j] == 0)
                break; //保证每个合数只会被它的最小质因数筛选一次
        }
    }

    printf("素数:\n");

    for (int i = 0; i < cnt; i++)
    {
        printf("%d\n", prime[i]);
    }

    printf("共有素数%d个\n", cnt);

    stop = clock(); /*停止计时*/
    duration = ((double)(stop - start)) / CLOCKS_PER_SEC; /*计算运行时间*/
    printf("Running time: %lf seconds\n", duration); // 输出运行时间

    return 0;
}

C语言 五种方法输出100以内的素数(质数) 源码

0.353秒

 


一、简单遍历

        这是一个简单的C语言程序,实现的功能是打印出2到100之间的所有素数。

        程序的基本思路是:用变量i从2开始逐个遍历到100,对于每一个i,用变量j从2开始逐个遍历到i-1,如果i能被j整除,则说明i不是素数,将isPrime标志位设为0,然后跳出循环。如果在循环结束后isPrime仍然是1,则说明i是素数,将其打印出来即可。

#include <stdio.h>

int main() {
    int i, j;
    for (i = 2; i <= 100; i++) {
        int isPrime = 1;
        for (j = 2; j < i; j++) {
            if (i % j == 0) {
                isPrime = 0;
                break;
            }
        }
        if (isPrime == 1) {
            printf("%d\n", i);
        }
    }
    return 0;
}

二、遍历至该数的平方根      

        程序的基本思路是:定义一个isprime函数,用来判断一个数是否为素数。isprime函数的实现方式与之前的程序相同,用一个循环遍历到该数的平方根即可。

        在主函数中,用for循环逐个枚举2到n之间的数字,如果这个数字是素数就打印出来,并将cnt计数器自增。最后输出素数的总个数。

        相较于之前的程序,这个程序代码更加简洁,可读性也更好,而且使用了一个新的函数来判断素数,使得程序更加模块化,代码复用性更高。

#include<stdio.h>
#include<math.h>

bool isprime(int x)
{
	for (int i = 2; i <=sqrt(x); i++)
	{
		if (x % i == 0) return 0;
	}
	return 1;
}

int main()
{
	int n, cnt = 0;
	scanf("%d", &n);
	for (int i = 2; i <= n; i++)
	{
		if (isprime(i))
		{
			cnt++;
			printf("%d\n", i);
		}
	}
	return 0;
}

三、用x/i来代替sqrt(x)

        对于i<=sqrt(x) sqrt函数的计算会比较慢,因此我们两边平方后,移一个i过去右边,变成i<=x/i 这样就能避免溢出的问题 。程序的代码基本与之前的程序相同,只是在函数isprime中的循环控制条件做了一下优化,用x/i来代替sqrt(x),达到减少循环次数的效果。

#include<stdio.h>


bool isprime(int x)
{
	for (int i = 2; i <= x / i; i++)
	{
		if (x % i == 0) return 0;
	}
	return 1;
}

int main()
{
	int n,cnt=0;
    double t1 = clock();
	scanf("%d", &n);
	for (int i = 2; i <= n; i++)
	{
		if (isprime(i))
		{
			cnt++;
			printf("%d\n", i);
		}
	}
	return 0;
}

四、朴素筛法

        一个合数一定存在非1非本身的质因子。

        程序的基本思路是:首先定义一个长度为n的数组pri,用来记录每一个数字是否是素数。然后用for循环遍历到n的平方根,如果i是素数,则用一个内部循环依次去除i的倍数,将这些数标记为合数。最后再用for循环遍历整个数组,将所有没有被标记过的数字输出出来。

        这个算法的优点在于避免了之前程序内部判断素数时的重复计算,同时减少了程序的循环次数。缺点是需要用一个数组来存储中间状态,可能会消耗更多的内存。

#include<stdio.h>
//0为素数,1为合数
int pri[100] = {0};

int main()
{
	int n,cnt=0;
	double t1 = clock();
	scanf("%d", &n);
	for (int i = 2; i <= n/i; i++)
	{
		if (!pri[i])//没被筛过
		{
			for (int j = 2 * i; j <= n; j += i)//去除合数
			{
				pri[j] = 1;
			}
		}
	}
	for (int i = 2; i <= n; i++)
	{
		if (!pri[i])
		{
			cnt++;
			printf("%d\n", i);
		}
	}
	return 0;
}

五、埃式筛法

        该程序是朴素筛法程序的一个修正,主要在内部循环的控制条件上做了改变。

        由于在之前的程序中,内部循环是从2 * i开始依次将i的倍数标记为合数。但在这个程序中,内部循环是从i * i开始依次将i的倍数标记为合数。这是因为在i * i之前,这些数字已经被其他的素数筛选过了,所以不需要再次去除。

        这个算法的优点和上一个程序的优点一样,避免了之前程序的重复计算,减少了程序的循环次数。同时由于内部循环的起始位置不同,也稍微提高了一点点程序的执行效率。

#include<stdio.h>
int pri[100] = {0};

int main()
{
	int n,cnt=0;
	double t1 = clock();
	scanf("%d", &n);
	for (int i = 2; i <= n/i; i++)
	{
		if (!pri[i])//没被筛过
		{
			for (int j = i * i; j <= n; j += i)//去除合数
			{
				pri[j] = 1;
			}
		}
	}
	for (int i = 2; i <= n; i++)
	{
		if (!pri[i])
		{
			cnt++;
			printf("%d\n", i);
		}
	}
	return 0;
}

六、欧拉筛法        

        欧拉筛法是一种高效的求解素数的算法,其本质基于线性筛法的思想。

        欧拉筛法的核心思想是筛去每个数的所有质因数,使得每个数只被它的最小质因数筛选一次。首先将2到n范围内的所有数都标记为素数,然后从2开始循环到n,对于每个数i,如果它是素数,则将其加入素数数组中,并将它的所有倍数(除了它本身)标记为合数。对于一个合数i*j,它已经被i筛选过了,所以其最小质因数一定是i,因此只需要将其标记一次即可。

        另外,为了保证每个合数都只会被它的最小质因数筛选一次,算法中添加了一个优化条件,即当i能够整除当前质数数组中的某个数j时,直接将i*j标记为合数,跳过后续的循环过程。

        欧拉筛法的时间复杂度为O(n),相比于朴素筛法和埃式筛法,具有更高的效率和更低的时间复杂度。

#include <stdio.h>
#include <stdbool.h>

int main()
{
    int n = 100;
    bool isPrime[101];
    int prime[101];
    int cnt = 0; //记录素数的个数
    for (int i = 2; i <= n; i++)
        isPrime[i] = true;

    for (int i = 2; i <= n; i++)
    {
        if (isPrime[i])
        {
            prime[cnt++] = i; //将i加入素数数组
        }
        for (int j = 0; j < cnt && i * prime[j] <= n; j++)
        {
            isPrime[i * prime[j]] = false; //将当前数与质因数的积标记为合数
            if (i % prime[j] == 0)
                break; //优化,保证每个合数只会被它的最小质因数筛选一次
        }
    }

    for (int i = 0; i < cnt; i++)
    {
         printf("%d\n", prime[i]);
    }

    return 0;
}

 

 

 

到了这里,关于C语言 五种方法输出100以内的素数(质数) 源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用C语言写一个100以内的素数的循环

    写出100以内的素数,首先确定思路,确定框架和可以用到的函数, 素数的特征就是除了1以外不能被被别的数整除。所以这个循环函数就用到for循环从2到100(因为1不是素数),在for循环内部判断这个数是否能被除了1之外的数整除,如果被整除则不为素数,接着下一个数继续

    2024年02月11日
    浏览(36)
  • Python-两种方法实现输出素数(质数)

    方案一: 程序的设计为: 1、设为被除数,取值范围可以自行设定,本例设为3-100;(1、2均不是素数) 2、设计为除数,除数的取值范围为除掉1和自身以及比自身大的数字(当被除数本身不为0时,除以比自身大的数余数一定不为零。) 3、在这两个前提下,先让固定,遍历范

    2024年02月11日
    浏览(30)
  • C语言:写一个代码,使用 试除法 打印100~200之间的素数(质数)

    使用 试除法 打印100~200之间 的 素数 。                素数(质数) : 一个数 只能被写成 一和本身的积 。 如: 7 只能写成 1*7 ,那就是素数(质数)了。                       =========================================================================                         (一)

    2024年02月08日
    浏览(64)
  • 求1000以内所有素数并输出的几种方法

    今天咱们来点不一样的,来看一下这样的一道题目,他要求我们把1-1000的素数全部找到并且输出 那我们先要了解什么是素数, 所谓素数,就是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数 。而合数则恰巧与素数相反,是指在大于1的整数中除了能被1和本

    2024年02月06日
    浏览(47)
  • C语言判断素数的三种方法 判断素数(质数)

    题目: 方法一:在2到n-1之间任取一个数,如果n能被整除则不是素数,否则就是素数 代码示例如下: 代码运行结果如下: 方法二:在2到n/2之间任取一个数,如果n能被整除则不是素数,否则就是素数  代码示例如下: 代码运行结果如下: 方法三:在2到sqrt(n)之间任取一个数,如

    2024年02月02日
    浏览(94)
  • python 100以内的质数

    可以使用for循环 要找出从1到100之间的质数,你可以使用嵌套循环和判断条件来实现。  

    2024年02月06日
    浏览(31)
  • C语言素数(质数)判断的三种方法

    本文介绍了判断素数的3种方法,从素数的概念分析,确定找到素数的几个必要条件,设计思路,并将代码进行优化。此外,还使用自定义函数的形式将同样的思路进行实现。 素数,就是仅能被自身和1整除的数字。 首先我们可以提取出判断素数的三个基本条件: 素数是整数

    2024年02月04日
    浏览(38)
  • C语言--输出1-100以内同时能被3和5整除的数

     首先我们要有1-100的数字.  如何表示同时能被3和5同时整除呢? 如果这个数i,i%3==0i%5==0,那么这个数就可以同时被3和5整除  最后输出即可  完整代码: 创作不易, 如果这份博客👍对你有帮助,可以给博主一个免费的点赞以示鼓励。 欢迎各位帅哥美女点赞👍评论⭐收藏⭐

    2024年02月03日
    浏览(30)
  • python123输出N以内的所有素数&哥德巴赫猜想&扑克牌游戏

    描述 ‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬ 编程找出N(即小

    2023年04月18日
    浏览(35)
  • C语言实现求n以内最大的k个素数c

    以下是C语言实现求n以内最大的k个素数的代码: 在该代码中,我们先定义了一个判断素数的函数 is_prime ,然后在 find_k_primes 函数中查找最大的k个素数。在查找的过程中,我们使用了一个计数器 count ,记录已经找到的素数个数,以及一个变量 max_prime ,记录已经找到的最大素

    2024年02月04日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包