C语言查找素数的几种实现方法及代码的优化

#include <stdio.h>

void main() {
	int x=1,i,j,k=0;

	printf("700到800之间的素数有:\n");

	for (i = 700; i <= 800; i++) {
		for (j = 2; j < sqrt(i); j++) {
			if ((i%j )!= 0) {
				if ((i-1)==j) {
					k++;
					printf("%d、", i);
					if (k % 6 == 0) {
						printf("\n");
					}
				}
			}
			else {
				break;
			}
		}
	}
	printf("\n700到800之间的素数共%d\n",k);
	
	getchar();

}
	

这里写图片描述
1、判断整数i(i>2)是否为素数即i约数只有1和它本身,转换成机器能识别的意思就是:i依次除以从2到i-1的余数全不为0.利用for循环可轻松从2除到i-1.

for (i = 700; i <= 800; i++) {
		for (j = 2; j < i; j++) {
		}
}

2、接下来就是判断了,这个可以有很多方法可以实现:(1)就是上面写的因为代码高亮显示粘贴会有错误标注所以直接粘贴为图片了:

if ((i%j )!= 0) {
				if ((i-1)==j) {
					k++;
					printf("%d、", i);
					if (k % 6 == 0) {
						printf("\n");
					}
				}
			}
			else {
				break;
			}

如果i/j余数为0,if判断为false,直接执行break关键字结束本次循环。第一个if判断成立并不一定就是素数,如9/2也可以通过第一个判断,但是并不是素数所以如下通过第二个if判断只有当从除以第一个到最后一个(i-1)依然没有break才是素数。
(2)第二种判断方法是:if ((i%j) == 0) {
break;
}
即通过判断i/j如果有余数就不是素数即break,结束本次循环。这个方法需要注意的是如果直接在这个判断后执行:

       if ((i%j) == 0) {
				break;
			}
			k++;
			printf("%d、", i);
			if (k % 6 == 0) {
				printf("\n");
			}			
		

如果这样找3到7的素数会得到结果:3、5、5、5、7、7、7、7……因为每次i/j,没有余数都会被当作素数执行后面的语句。可以通过变量x得到循环中i值,再用if判断如果已经输出过则不再输出if(x!=i)……
(3)可以通过立flag,根据返回值得到0、1(真、假),执行相应的语法:

if ((i%j) == 0) {
				return x = 1;
				break;
			}

3、

if (k % 6 == 0) {
				printf("\n");
			}	

这句就是每六个\n换行输出,也可以通过建立数组方式得到同样的结果:
int a[][6];
这种方式由于素数数量不确定会得到a多余的默认值0.并且C语言不支持不完整的数组,所以需要判断a[][]每个数是否为零进行输出判断。
4、以上截图中这个方法实现素数输出最大的失败就是循环使用printf输出结果,结果就是造成不必要的效能浪费,如果是一个复杂的循环计算不停的循环使用printf极大造成计算机负担。而这种完全可以解决:
int a[];
……

if ((i%j )!= 0) {
				if ((i-1)==j) {
					k++;
                      a[k]=i;
					}
				}
			}

由a[k]=i;将素数i的值储存在数组a中,只要最后在数组中输出一次就可以了,也可以用a[][[6]方式重新排列输出每六个一行。还可以转换成char类型,用str[]储存方便一次输出。
/*
另外这个素数判断条件也需要改进,i/j一直除到i-1,完全没有必要。除到i/2就可以了,如7/2、7/3、就够了,除到i/2就可以判断是否为质数了。
5、
循环结束后k的值就是素数个数,直接输出即可:

printf("\n700到800之间的素数共%d\n",k);

最后加上一句:

getchar();

要不然运行时一闪而过,加上后只有取得下一个字符输入才会结束。

以上只是为了完成作业报告写的,而如果真正判断素数我一定会

#include <stdio.h>

void main() {
    int x,y,i,j,k=0;

    printf("请输入素数判断下限x和上限y\n");
    scanf("%d%d",&x,&y);

    for (i = x; i <= y; i++) {
    ......//此处不变
            }
    printf("\n%d到%d之间的素数共%d\n",x,y,k);

    getchar();
}

需求是无止境的,如果下次换个范围,这么简单的需求难道还要重新进去修改i的值吗?只需要设置变量x,y通过scanf传入,并传给i,得到素数的上限,下限,求之间素数。
6、如果真是一个程序i项目,考虑到程序的维护性,建议将这个计算过程封装成函数,无论是可维护性还是简洁性都会提高。

#include <stdio.h>

int get_prime(int x,int y) {
    int i,j,k=0;
    
    printf("请输入素数判断下限x和上限y\n");
    for (i = x; i <= y; i++) {
    ......//此处不变
            }
    printf("\n%d到%d之间的素数共%d\n",x,y,k);

    getchar();
}
void main(){
	scanf("%d%d",&x,&y);
	get_prime(x,y);
}

封装成函数直接调用get_prime传值计算,main函数则较少代码区可以更自由进行其他活动。


以上全是C语言实现的,如果用Java等高度自由的面向对象高级语言,灵活的运用函数、继承、接口,会更简洁的计算得到相同结果。如果是Python,极简的代码,三五行就可以完成判断得到结果。简单的语言并不都是好的,因为高级语言转换成机器语言,例如python,你的极简的代码,就意味着转换成机器语言这个过程的复杂,对于一个稍微卡顿的计算机,会明显感受到运算的迟滞。当然这些也是可以通过改变语法实现就像上面4说的将printf等系统封装函数移至循环外围。然而转换成机器语言到的过程这些是无法通过改变语法完全改善的,所以高级语言的流行绝对不是另一个语言的灭亡,每一个语言都有独到的优点,这些优点也伴随着巨大的不足。另外判断到sqrt()平方根就行

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值