C语言初学素数的求解方法

1.素数的定义

素数就是质数,有无限个。除了1和该数本身以外不再有其他的因数的数被称为素数,比如2=1×2;5=1×5;23=1×23;……所以2、5和23就是素数。值得注意的是,0 与 1 既不是素数,也不是合数。

2.素数的求解方法

1.直接求解:

我们如何用程序判断一个数是不是素数呢?(比如设这个数为i)最简单的方法3.就是,用这个数i去整除2~i-1;比如判断10,是不是素数, 1 2 3 4 5 6 7 8 9 10;,我们就可以用10去试除2-9,如果其中存在能把10整除的数,比如5,那么10就不是素数,如果没有能把10整除的数,那么10就是素数。

d44a7e714418485fa9a74171a92a13aa.png

附上源码大家体验效果:

int main()
{
	int i = 0;
	printf("请输入你想要判断的数:\n");
	scanf("%d", &i);
	int j = 0;
	for (j = 2; j < i; j++)
	{
		if (i % j == 0)
			break;
	}
	if (i == j)
	{
		printf("%d是素数\n",i);
	}
	else
	{
		printf("%d不是素数\n",i);
	}
	return 0;
}

3.试除法优化思路

引入另外一个例子,我们已经知道了如何求解素数,那么,我们可以编写一个函数来判断一下 100-200之间有多少个素数吗?再打印出来。

思路:

我们首先应该产生100-200之间的数字,外层for循环可以搞定

然后用第二个循环遍历第一个循环产生的数字2~i-1,来判断他是不是素数,是就答应并且计数。

b9b33b825de847f3b4d36cdc67918210.png

附上源码大家体验效果:

int main()
{
	int i = 0;
	int count = 0;


	// 外层循环用来获取100~200之间的所有数据,100肯定不是素数,因此i从101开始
	for (i = 101; i <= 200; i++)
	{
		//判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数
		int j = 0;
		for (j = 2; j < i; j++)
		{
			if (i % j == 0)
			{
				break;
			}
		}

		// 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数
		if (j == i)
		{
			count++;
			printf("%d ", i);
		}
	}


	printf("\ncount = %d\n", count);
	return 0;
}

但是,我们想一下:

1.100到200之间的数字,我们都要遍历一遍,有必要吗?

我们知道的,偶数一定不是素数,所以在外层循环我们就没有必要再产生偶数

可以将外层循环控制条件i++改成i+=2,每次产生顺序奇数。 

2.对于内层循环的一个功能,我们就是去遍历找外层循环产生的数字i的因子嘛,那我们来看一下:

如果 i= 9    9 = 1*9    9 = 3*3        9开平方 = 3

        i = 16  16 = 1*16=2*8= 4*4   16开平发 = 4

        i = 8      8 = 1*8 = 2*4              8开平方>2

那我们总结一个规律,一个数的因子中除了1,只要能被整除,有一个因子一定小于这个数的开平方。那我的内层循环就可以改为:j<i -> j<sqrt(i)

补充:sqrt()库函数,用于求一个数的开平方

     头文件  math.h 

优化:

int main()
{
	int i = 0;
	int count = 0;


	// 外层循环用来获取100~200之间的所有数据,100肯定不是素数,因此i从101开始
	for (i = 101; i <= 200; i+=2)
	{
		//判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数
		int j = 0;
		for (j = 2; j <=sqrt(i); j++)
		{
			if (i % j == 0)
			{
				break;
			}
		}

		// 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数
		if (j > sqrt(i))
		{
			count++;
			printf("%d ", i);
		}
	}


	printf("\ncount = %d\n", count);
	return 0;
}

虽然运行结果是一样的,但是当我们要判断100-200之间的数是否有素数的时候,只用判断一半数据,而且更舒服的是对于内层循环来说,当要判断像100这种数据是不是素数,就不用遍历2——99,只用遍历1——9,做到了指数层级别的优化。非常nice。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值