1. 程式人生 > >學以致用——Java原始碼——任意範圍內的素數列印(Prime Number display)

學以致用——Java原始碼——任意範圍內的素數列印(Prime Number display)

看起來很簡單的一個程式,寫起來咋就這麼費時間呢?或許這就是所謂的知易行難吧。

當上限增加到10萬時(即,輸出10萬以內的所有素數時,方法1用時約為方法2的四分之一)。選擇一個優化的演算法有時很重要!

原始碼:

package exercises.ch6Methods;


//JHTP Exercise 6.25 (Prime Numbers)
//by [email protected]
/*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

已退出程式