求质数的几种方式(详细过程)

1.首先最简单暴力的方法,那就是判断某数是否为质数时,就除以小于该数的所有数,若一个都不能被整除,则该数为质数,代码如下

void panduanzhishu(int m)
{
	
	for (int i = 2; i < m; i++)
	{
		if (m % i == 0)
		{
			printf("不是质数");
			return;
		}
	}
	printf("是质数");

}

而下面代码是基于上面代码,求出基于4~m内所有的质数

int main()
{
	int m = 0;
	scanf("%d", &m);
	for (int j = m; j > 4; j--)
	{
		int i = 2;
		for (i = 2; i < j; i++)
		{
			if (j % i == 0)
			{
				break;
			}
		}
		if (j == i)
		{
			printf("%d", j);
			printf(" ");
		}
	}
	return 0;
}

2.稍微复杂的求解质数的方法,运用的数学知识代码如下

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

// 函数isPrime用于判断一个整数是否为质数,接受一个整数参数n,返回一个布尔值
bool isPrime(int n) {
    // 如果n小于等于1,根据质数定义(质数大于1),不是质数,返回false
    if (n <= 1) {
        return false;
    }
    // 如果n小于等于3,2和3是质数,直接返回true
    if (n <= 3) {
        return true;
    }
    // 如果n能被2或者3整除,那它不是质数,返回false
    if (n % 2 == 0 || n % 3 == 0) {
        return false;
    }
    // 从5开始,每次加6进行判断,因为除了2和3之外的质数都可以表示为6k ± 1的形式(k为整数)
    int i = 5;
    while (i * i <= n) {
        // 如果n能被i或者i + 2整除,说明n不是质数,返回false
        if (n % i == 0 || n % (i + 2)==0) {
            return false;
        }
        i += 6;
    }
    // 如果经过上述判断都没有返回false,说明n是质数,返回true
    return true;
}

int main() {
    int num;
    // 提示用户输入一个整数
    printf("请输入一个整数: ");
    // 获取用户输入的整数
    scanf("%d", &num);
    // 调用isPrime函数判断num是否为质数,如果是则输出是质数,否则输出不是质数
    if (isPrime(num)) {
        printf("%d是质数\n", num);
    } else {
        printf("%d不是质数\n", num);
    }
    return 0;
}
 int i = 5;
 while (i * i <= n) 
{
  if (n % i == 0 || n % (i + 2)==0) 
{
   return false;
} 
   i += 6;
}

这一小段代码详细解释一下

  1. 代码段整体功能
    • 这部分代码主要是用于进一步判断一个大于3的数n是否为质数。它基于一个数学规律:除了2和3之外的质数都可以表示为6k ± 1k为整数)的形式。所以它通过循环检查n能否被这些可能是质数的数整除。
  2. 具体代码解释
    • int i = 5;
      • 初始化一个变量i为5。这里选择5是因为前面已经单独处理了2和3的情况,而5是第一个符合6k - 1(当k = 1时)形式的数,用于开始后续的判断。
    • while (i * i <= n)
      • 这个循环条件的意义是只要i的平方小于等于n,就继续循环。这是因为如果一个数n有大于sqrt(n)(这里用i来表示,当i * i<=n时,i <= sqrt(n))的因数,那么它必然也有小于sqrt(n)的对应因数。所以只需要检查到sqrt(n)就可以判断n是否为质数了。
    • if (n % i == 0||n % (i + 2)==0)
      • 这里检查n能否被i或者i+2整除。根据前面提到的规律,除了2和3之外的质数都可以表示为6k ± 1的形式,所以i代表6k - 1形式的数,i + 2代表6k+1形式的数。如果n能被这些数整除,那么n就不是质数,所以返回false
    • i += 6;
      • 在每次循环后,将i增加6。这是因为下一个可能是质数的数(根据6k ± 1的形式)需要通过增加6来得到。例如,当i = 5时,下一个要检查的数是115+6),再下一个是1711 + 6)等。

这个循环条件的意义是只要i的平方小于等于n,就继续循环。这是因为如果一个数n有大于sqrt(n)(这里用i来表示,当i * i<=n时,i <= sqrt(n))的因数,那么它必然也有小于sqrt(n)的对应因数。所以只需要检查到sqrt(n)就可以判断n是否为质数了。 这里再用严谨的数学逻辑推导一下

  1. 假设存在大于nn​的因数
    • 设nn为一个正整数,假设nn有一个因数aa,且a>na>n​。
    • 因为aa是nn的因数,所以存在另一个因数bb,使得n=a×bn=a×b。
    • 那么b=nab=an​。
    • 由于a>na>n​,则b=na<nn=nb=an​<n​n​=n​。
  2. 结论
    • 这就说明,如果nn有一个大于nn​的因数aa,那么必然存在一个小于nn​的因数bb。
    • 在判断一个数nn是否为质数时,我们只需要检查到nn​就足够了。因为如果在22到nn​这个范围内没有找到nn的因数,那么大于nn​的数也不可能是nn的因数(否则就会存在上述矛盾的情况)。所以在代码中通过i∗i⩽ni∗i⩽n(等价于i⩽ni⩽n​)这个条件来限制循环范围,从而提高判断质数的效率。

除了2和3之外的质数都可以表示为6k ± 1的形式(k为整数) 这里再用严谨的数学逻辑推导一下

  1. 整数的余数分类
    • 设nn为大于33的整数。当nn除以66时,根据余数定理,余数rr的取值范围是0⩽r<60⩽r<6,所以nn可以表示为n=6k+rn=6k+r,其中k∈Zk∈Z(整数集),r∈{0,1,2,3,4,5}r∈{0,1,2,3,4,5}。
  2. 分析各种余数情况
    • 当r=0r=0时,n=6kn=6k,显然nn能被66整除,nn不是质数(因为n>3n>3)。
    • 当r=2r=2时,n=6k+2=2(3k+1)n=6k+2=2(3k+1),能被22整除,不是质数(因为n>3n>3)。
    • 当r=3r=3时,n=6k+3=3(2k+1)n=6k+3=3(2k+1),能被33整除,不是质数(因为n>3n>3)。
    • 当r=4r=4时,n=6k+4=2(3k+2)n=6k+4=2(3k+2),能被22整除,不是质数(因为n>3n>3)。
  3. 剩余可能的质数形式
    • 当r=1r=1时,n=6k+1n=6k+1。
    • 当r=5r=5时,n=6k+5n=6k+5,而6k+5=6(k+1)−16k+5=6(k+1)−1,可以表示为6m−16m−1(令m=k+1m=k+1)。
  4. 结论
    • 所以,除了22和33之外的质数(因为22、33是特殊情况,不满足这种形式)都可以表示为6k±16k±1的形式(k∈Zk∈Z)。

所以i代表6k - 1形式的数,i + 2代表6k+1形式的数。如果n能被这些数整除,那么n就不是质数,所以返回false。 这里再用严谨的数学逻辑推导一下

  1. 基于质数形式的假设
    • 已知除了22和33之外的质数都可以表示为6k±16k±1(kk为整数)的形式。
    • 我们设i=6k−1i=6k−1(kk为整数),那么i+2=(6k−1)+2=6k+1i+2=(6k−1)+2=6k+1。
  2. 分析整除性与质数的关系
    • 对于一个数nn(n>3n>3),如果nn能被i=6k−1i=6k−1整除,即n=m×(6k−1)n=m×(6k−1)(mm为整数),那么nn除了11和nn本身外还有其他因数(6k−16k−1和mm),根据质数的定义,nn不是质数,所以返回falsefalse。
    • 同理,如果nn能被i+2=6k+1i+2=6k+1整除,即n=p×(6k+1)n=p×(6k+1)(pp为整数),那么nn除了11和nn本身外还有其他因数(6k+16k+1和pp),nn不是质数,也应返回falsefalse。
  3. 结论
    • 所以在判断一个数nn是否为质数的代码中,如果nn能被ii或者i+2i+2整除(ii代表6k−16k−1形式的数,i+2i+2代表6k+16k+1形式的数),那么nn就不是质数,所以返回falsefalse。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值