质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。所以2是最小的质数。
二、实现质数的输出 1.实现方式一代码如下(示例):
说明:第一层for循环用来遍历100以内的自然数,因为2是最小的质数并且所有的整数值都可以被1整除,所以这里我们直接把int i赋值为2,让i从2开始遍历到100结束,接着当执行到第二层for循环的时候,用来判断从2开始,到本次i-1结束为止,是否有能够整除i的数值,如果有可以整除i的数值,则isFlag将会从true变为false,之后通过if条件判断语句判断isFlag确定本次的i是否为质数,是则输出i否则不输出,最后需要将isFlag重置为true。
public class PrimeNumberTest {
public static void main(String[] args) {
boolean isFlag = true;// 标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <= 100; i++) {// 遍历100以内的自然数
for (int j = 2; j < i; j++) {// j:被i去除
if (i % j == 0) {// i被j除尽
isFlag = false;
}
}
if (isFlag == true) {
System.out.println(i);
}
// 重置isFlag
isFlag = true;
}
}
}
1)对方式一的第一种优化
代码如下(示例):
说明:
相较于上述的方式一,我们可以在内层循环中的if条件判断语句内部添加break关键字,这样做的好处在于,当通过if条件判断语句确定i为非质数的情况下,则无需再继续往下执行内层for循环,可通过break关键字来结束当前循环,进行判断下一个i是否为质数,节省了时间上的成本,效率更快。
这里为了让大家看到运算速率上的差别,我们将100以内的遍历,改为100000以内的遍历。
/*
100000以内的所有质数的输出。实现方式一
质数:素数,只能被1和它本身整除的自然数。-->从2开始,到这个数-1结束为止,都不能被这个数本身整除。
对PrimeNumberTest.java文件中质数输出问题的优化一
*/
class PrimeNumberTest1 {
public static void main(String[] args) {
// 获取当前时间距离1970-01-01 00:00:00 的毫秒数
long start = System.currentTimeMillis();
boolean isFlag = true;// 标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <= 100000; i++) {// 遍历100000以内的自然数
for (int j = 2; j < i; j++) {// j:被i去除
if (i % j == 0) {// i被j除尽
isFlag = false;
break;//优化一:只对本身非质数的自然数是有效的
}
}
if (isFlag == true) {
System.out.println(i);
}
// 重置isFlag
isFlag = true;
}
// 获取当前时间距离1970-01-01 00:00:00 的毫秒数
long end = System.currentTimeMillis();
System.out.println("所花费的时间为" + (end - start));
}
}
2)对方式一的第二种优化
代码如下(示例):
说明:
相对于第二层for循环来说,可以通过Math.sqrt()这个函数来代替从2到i-1的遍历,此方式比第一种优化方式更高效,时间成本上有很大的节约。
/*
100000以内的所有质数的输出。实现方式一
质数:素数,只能被1和它本身整除的自然数。-->从2开始,到这个数-1结束为止,都不能被这个数本身整除。
对PrimeNumberTest.java文件中质数输出问题的优化二
*/
class PrimeNumberTest2 {
public static void main(String[] args) {
// 获取当前时间距离1970-01-01 00:00:00 的毫秒数
long start = System.currentTimeMillis();
int count = 0;//记录质数的个数
boolean isFlag = true;// 标识i是否被j除尽,一旦除尽,修改其值
for (int i = 2; i <= 100000; i++) {// 遍历100000以内的自然数
//优化二:对本身是质数的自然数是有效的
for (int j = 2; j <= Math.sqrt(i); j++) {// j:被i去除
if (i % j == 0) {// i被j除尽
isFlag = false;
break;//优化一:只对本身非质数的自然数是有效的
}
}
if (isFlag == true) {
// System.out.println(i);
count++;
}
// 重置isFlag
isFlag = true;
}
// 获取当前时间距离1970-01-01 00:00:00 的毫秒数
long end = System.currentTimeMillis();
System.out.println("质数的个数为:" + count);
System.out.println("所花费的时间为" + (end - start));
}
}
2.实现方式二
代码如下(示例):
说明:
第二种实现方式在上述第二种优化方式的基础上进行了改动,将之前与isFlag相关的部分全部去掉,在if条件判断语句内部使用带标签的continue关键字代理break关键字,从而在不降低效率的情况下,还减少了代码的冗余,让代码更简洁。
/*
100000以内的所有质数的输出。实现方式二
质数:素数,只能被1和它本身整除的自然数。-->从2开始,到这个数-1结束为止,都不能被这个数本身整除。
*/
class PrimeNumberTest3 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
int count = 0;
label:for (int i = 2; i <= 100000; i++) {
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
continue label;
}
}
//能执行到此步骤的,都是质数
count++;
}
long end = System.currentTimeMillis();
System.out.println("质数的个数为:" + count);
System.out.println("所花费的时间为" + (end - start));
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)