求解素数各种方法,代码优化,求最大公约数以及判断闰年的详解笔记

求两个数的最大公约数

方法一:

#include
int main()
{
     
    int m=0;
    int n=0;
    printf("请输入两个数:\n");
    scanf("%d %d",&m,&n);
    int min=0;//m和n中的较小值
    if(m>n)
    {
     
        min=n;
    }
    else
    {
     
        min=m;
    }
    while(1)
    {
     
        if(m%min==0&&n%min==0)
        {
     
            printf("最大公约数是:%d\n",min)
            break;
        }
        min--;
    }
    return 0;
}

思路:因为两个数的最大公因数不可能大于这两个数,先求出m与n当中的较小值,然后设置一个循环,循环里面判断,满足判断条件,输出然后break;不满足,min–,继续判断。

方法二:

辗转相除法

#include
int main()
{
     
    int m=0;
    int n=0;
    printf("请输入两个数:\n");
    scanf("%d %d",&m,&n);
    int t=0;
    while(m%n)
    {
     
        t=m%n;
        m=n;
        n=t;
    }
    printf("最大公约数为:%d\n",n);
    return 0;
}

代码解释:

求解素数各种方法,代码优化,求最大公约数以及判断闰年的详解笔记_第1张图片

打印1000年-2000年之间的闰年

首先我们要明白判断闰年的方法

1.被4整除,但不能被100整除就是闰年

2.能被400整除是闰年

知道这个的话下面的代码就很好理解了。

#include
int main()
{
     
    int year=0;
    for(year=1000;year<=2000;year++)
    {
     
        if(year%4==0&&year%100!=0)
        {
     
            printf("%d ",year);
        }
        if(y%400==0)
        {
     
            printf("%d ",year);
        }
    }
    return 0;
}

精简版:

#include
int main()
{
     
    int year=0;
    for(year=1000;year<=2000;year++)
    {
     
        if(year%4==0&&year%100!=0||year%400==0)
        {
     //&& 与逻辑操作符 ||或逻辑操作符
            printf("%d ",year);
        }

    }
    return 0;
}

打印100-200之间的素数

素数-质数
只能被1和它本身整除

方法一:

#include
int main()
{
     
	int i = 0;
    int count = 0;
	for (i = 100; i <= 200; i++)
	{
     
		//判断i是否为素数
		//2->i-1之间的素数去试除,看能不能整除
		int j = 0;
		for (j = 2; j < i; j++)
		{
     
			if (i % j == 0)
			{
     
				break;
			}
		}
		if (i == j)
		{
     
            count++;
			printf("%d ", i);//当j一直加加,直到加到i=j,出来,所以i是素数
		}
	}
    	printf("\ncount=%d", count);
	return 0;
}

代码解释:

判断i是否为素数,我们需要让2到i-1之间的素数去试除,看能不能整除,如果能整除,则break跳出循环,当break跳出循环时意味着当前i值不是素数,我们在循环外面给定一个判断条件,我们在这里想一想,当i一直不能整除j时,j一直++,加到j=i会出循环,当break跳出时,i必定不等于j,所以我们在循环外面给定i是否等于j的判断条件,满足则是素数。

方法二:

#include
int main()
{
     
	int i = 0;
	int count = 0;
	for (i = 100; i <= 200; i++)
	{
     
		//判断i是否为素数
		//2->i-1之间的素数去试除,看能不能整除
		int flag = 1;//假设i就是素数
		int j = 0;
		for (j = 2; j < i; j++)
		{
     
			if (i % j == 0)
			{
     
				flag = 0;//不是素数
				break;
			}
		}
		if (flag == 1)
		{
     
			count++;
			printf("%d", i);//素数
		}
	}
	printf("\ncount=%d", count);
	return 0;
}

代码解释:

这里我们和方法一不一样的是,我们修改了判断条件,我们添加了一个标志flag,令他等于1时就是素数,在循环里面当j能整除i时,我们将flag赋为0,所以出循环时,判断条件为若flag为1则为素数。

方法三:

此方法在上面方法的基础上进行了优化

#include
int main()
{
     
	int i = 0;
	int count = 0;
	//m=a*b
	//a和b中一定至少有一个<=sqrt(m)开平方m的
	//16=2*8=4*4
	for (i = 100; i <= 200; i++)
	{
     
		//判断i是否为素数
		//2->i-1之间的素数去试除,看能不能整除
		int flag = 1;
		int j = 0;
		for (j = 2; j <=sqrt(i); j++)
		{
     				//math.h
			if (i % j == 0)
			{
     
				flag = 0;//不是素数
				break;
			}
		}
		if (flag == 1)
		{
     
			count++;
			printf("%d", i);//素数
		}
	}
		printf("\ncount=%d", count);
		return 0;
	}

代码解释:

我们仔细想想发现,16=2*8=4*4,sqrt(16)=4,我们判断了2能整除16,就不用在判断8能整除16了。我们可以得出结论:

m=a*b
a和b中一定至少有一个<=sqrt(m)开平方m的,所以我们可以只判断2到sqrt(i)之间的数是不是能整除i,这样大大减少了循环次数,得到了优化

方法四:

其实我们可以再进一步进行优化,看下面代码

#include
int main()
{
     
	int i = 0;
	int count = 0;
	for (i = 101; i <= 200; i+=2)//只判断奇数
	{
     
		//判断i是否为素数
		//2->sqrt(i)之间的素数去试除,看能不能整除
		int flag = 1;
		int j = 0;
		for (j = 2; j <=sqrt(i); j++)
		{
     				//math.h
		//if (i % j == 0)
		//{
     
		//	flag = 0;//不是素数
		//	break;
		//}
		}
		if (flag == 1)
		{
     
			count++;
			printf("%d", i);//素数
		}
		printf("\ncount=%d", count);
	}
	return 0;

代码解释:

我们知道偶数都能除以2,所以偶数不可能是素数,所以我们只判断奇数是不是素数,将循环中i的初始化改为i=101,调整部分改为i+=2即可,是不是更加将代码优化了呢。

欢迎大家前来学习交流!

你可能感兴趣的:(c语言)