学以致用——Java源码——任意范围内的素数打印(Prime Number display)

本文探讨了素数判定的两种方法,通过对比优化前后的算法,展示了在处理大规模数据时,选择合适算法的重要性。实验结果显示,当上限提高至10万时,优化后的算法执行时间仅为未优化算法的四分之一。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看起来很简单的一个程序,写起来咋就这么费时间呢?或许这就是所谓的知易行难吧。

当上限增加到10万时(即,输出10万以内的所有素数时,方法1用时约为方法2的四分之一)。选择一个优化的算法有时很重要!

源码:

package exercises.ch6Methods;


//JHTP Exercise 6.25 (Prime Numbers)
//by pandenghuang@163.com
/*6.25 (Prime Numbers) A positive integer is prime if it’s divisible by only 1 and itself. 
 * For example, 2, 3, 5 and 7 are prime, but 4, 6, 8 and 9 are not. 
 * The number 1, by definition, is not prime.
 * a) Write a method that determines whether a number is prime.
 * b) Use this method in an application that determines and displays all the prime numbers less than 10,000. 
 *    How many numbers up to 10,000 do you have to test to ensure that you’ve found all the primes?
 * c) Initially, you might think that n/2 is the upper limit for which you must test to see whether a number n is prime, 
 *    but you need only go as high as the square root of n. Rewrite the program, and run it both ways.
*/
import java.util.Scanner;

public class PrimeNumberTest 
{
/*
 * // 基于2008年applet版本修改:
 * 1. 改正了将1判定为质数的bug
 * 2. 添加了注释
 * 3. 取消了flag局部变量
 * 
 */		 
public static boolean IsPrime1(int argument) 
{
	   if (argument ==1)
		   return false; //1既不是质数,也不是合数
	   else
	   {
	   for (int i=2;i<=Math.sqrt(argument);i++)  //当要判断的数为2,3时,循环继续的条件不满足,循环体语句不会被执行,方法返回true
	     {
	        if (argument%i==0)
	             return false;  //2到该整数的平方根取整之间出现了能被该整数整除的数字,判定为合数
	   }
	   return true;  //运行到这里,说明不是合数,也不是1,即为质数
	   }
	}
	   
//以下为方法2,不是最优化的算法(循环继续的条件中的上限值未优化)	   
public static boolean IsPrime2(int argument)
{
	   if (argument ==1)
		   return false;
	   else
	   {
	   for (int i=2;i<argument;i++)
	     {
	        if (argument%i==0)
	             return false;  //2到该整数的平方根取整之间出现了能被该整数整除的数字,判定为合数
	   }
	   return true;  //运行到这里,说明不是合数,即为质数
	   }
	}
	
	
public static void main(String[] args)
{
	int size=0;
	int count=0;
	double duration=0.0;
	
	Scanner input=new Scanner(System.in);
	
	do {
		count=0; //计数器清零
		System.out.print("请输入上限(整数,输入-1退出):");
		size=input.nextInt();
		if(size==-1)
			{System.out.print("已退出程序");
			    break;
		    }
		System.out.print("请输入下限(整数,输入-1退出):");
		int start=input.nextInt();
		if(start==-1)
			{System.out.print("已退出程序");
			    break;
		    }
		System.out.print("请选择素数判定方法,1为优化方法,2为普通方法(整数,输入-1退出):");
		int methodUsed=input.nextInt();
		if(methodUsed==-1)
			{System.out.print("已退出程序");
			    break;
		    }
		else{
			if (methodUsed == 1)
			{
				long beginTime=System.currentTimeMillis();
				for (int i=start;i<=size;i++){
					if (IsPrime1(i)){
						System.out.printf("%d\t",i);
						count++;
						if (count%12==0)
							System.out.println();
					}
				}
			    long endTime=System.currentTimeMillis();
				duration=(double)(endTime-beginTime)/1000;
				System.out.printf("\n%d至%d之间的素数共有以上%d个,方法1共用时%.2f秒。\n\n",start,size,count,duration);
			}
			else if (methodUsed == 2)
			{
				long beginTime=System.currentTimeMillis();
				for (int i=start;i<=size;i++){
					if (IsPrime2(i)){
						System.out.printf("%d\t",i);
						count++;
						if (count%10==0)
							System.out.println();
					}
				}
				long endTime=System.currentTimeMillis();
				duration=(double)(endTime-beginTime)/1000;
				System.out.printf("\n%d至%d之间的素数共有以上%d个,方法2共用时%.2f秒。\n\n",start,size,count,duration);
			}

			
	}
	}
	while (size!=-1);
	
	input.close();
}
}

运行结果:

请输入上限(整数,输入-1退出)100000000

请输入下限(整数,输入-1退出)99999000

请选择素数判定方法,1为优化方法,2为普通方法(整数,输入-1退出)1

99999043  99999073  99999077  99999079  99999089  99999103  99999113  99999131 

99999157  99999167  99999187  99999217  99999247  99999257  99999259  99999307 

99999323  99999329  99999343  99999353  99999373  99999401  99999437  99999439 

99999481  99999509  99999517  99999539  99999541  99999547  99999551  99999563 

99999587  99999589  99999611  99999617  99999623  99999643  99999677  99999703 

99999721  99999773  99999787  99999821  99999827  99999839  99999847  99999931 

99999941  99999959  99999971  99999989 

99999000100000000之间的素数共有以上52个,方法1共用时0.02秒。

 

请输入上限(整数,输入-1退出)-1

已退出程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值