[英]printing Prime numbers in java
此 Java 代码打印出 2-100 之间的素数。
这很好用。
这段代码不是我做的。
但我试图弄清楚这段代码发生了什么。
谁能告诉我第二个(for)循环之后发生了什么?
class primenumbers{
public static void main(String args[])
{
int i, j;
boolean isprime;
for(i=2; i < 100; i++) {
isprime = true;
// see if the number is evenly divisible
for(j=2; j <= i/j; j++)
// if it is, then its not prime
if((i%j) == 0) isprime = false;
if(isprime)
System.out.println(i + " is prime.");
}
}
}
外部(第一个)循环枚举 [2,100) 中的所有数字。
内部(第二个)循环检查来自第一个循环的当前数字是否可以被任何东西整除。
此检查使用%
(remainder): (i%j)==0
当i
除以j
的余数为0
时完成。 根据定义,当余数为零时, i
可被j
整除,因此不是素数: isprime=false
。
你只需要检查[2,i/j]
因为你只需要检查到sqrt(i)
(上一节中的解释)。
话虽如此,内部循环可以重写为:
...
int s = sqrt(i);
for(j=2; j <= s; j++)
...
但是sqrt
比除法更昂贵,因此最好将j<=sqrt(i)
重写为(两边平方) j^2 < i
和j*j<i
和j<i/j
。 当j
足够大时, j*j
可能会溢出,因此在最后一步中双方都被j
除。
sqrt(i)
的解释取自这里: 为什么我们要检查素数的平方根以确定它是否为素数?
如果i
不是素数,则存在一些x
使得i = x * j
。 如果x
和j
都大于sqrt(i)
则x*j
将大于i
。
因此,其中至少一个因子(x 或 j)必须小于或等于i
的平方根,并且要检查i
是否为素数,我们只需要测试小于或等于平方根的因子。
这是对埃拉托色尼筛法的改进。
首先,我将总结一下 Eratosthenes 的筛子的作用,如果您已经知道这一点,可以跳到最后一段。 Eratosthenes 算法的筛子循环穿过某个数字边界。 (比如说 2 - 100)。 对于它循环的每个数字,它都会抵消倍数,例如,因为 2 是质数(真),所以 2 的所有倍数都不是(它们是假的)。 3、5 等相同; 并且该算法跳过每个预定的非质数。 因此,该算法的模拟将是:
2 ---prime number... cancels out 4, 6, 8, 10, 12....
3 ---prime number... cancels out 6, 9, 12, 15, 18...
4 --- ALREADY CANCELLED OUT... Skip
5 --- prime number... cancels out 10, 15, 20, 25...
6 --- ALREADY CANCELLED OUT... Skip
因此,未被取消的数字是质数。 您还可以阅读此内容以获取更多信息: http ://www.geeksforgeeks.org/sieve-of-eratosthenes/
现在,对于您的问题,您的算法循环遍历数字列表。 对于每个数字(比如 x),它检查循环通过 (i / j) 的任何先前数字是否是 x 的因子。 之所以使用i/j作为第二个 for 循环的边界,是为了提高效率。 如果您正在检查 10(例如)是否是质数,则无需检查 6 是否是一个因数。 您可以方便地停在 n/(n/2)。 这就是该部分试图实现的目标。
第一个循环仅用于生成从 2 到 100 的数字。
第二个循环尝试查找该数字是否可以被任何其他数字整除。 在这里,我们尝试将一个数字与一组数字(2 到 prime_index)相除。
假设数字是10
,第一次迭代(j = 2)的素数索引是10/2 = 5
。 这意味着,如果数字10
不能被 2 到 5 之间的任何数字整除,则它是质数。 它本身可以被2
整除,使其成为非质数。
假设数字是 9,现在第一次迭代(j = 2)的素数索引是9/2 = 4
。 现在, 9 % 2
给出 1 作为提醒。 因此,循环继续进行第二次迭代(j = 3)。 现在素数索引是9/3 = 3
(注意这里素数索引值从 4 减少到 3 )所以,现在如果数字不能被3
整除,则它被确定为素数。
因此,对于每次迭代,素数索引都会减少,从而减少迭代次数。
Example for Number 97,
j = 2, prime index = 97/2 = 48 (no of iterations for loop)
j = 3, prime index = 97/3 = 32 (no of iterations for loop)
j = 4, prime index = 97/4 = 24 (no of iterations for loop)
j = 5, prime index = 97/5 = 19 (no of iterations for loop)
j = 6, prime index = 97/6 = 16 (no of iterations for loop)
j = 7, prime index = 97/7 = 13 (no of iterations for loop)
j = 8, prime index = 97/8 = 12 (no of iterations for loop)
j = 9, prime index = 97/9 = 10 (no of iterations for loop)
j = 10, prime index = 97/10 = 9 (loop exits as condition failed 10 <= 9 and declares 97 as a prime number)
现在,这里的循环实际上进行了 10 次迭代,而不是建议的 48 次迭代。
让我们修改代码以便更好地理解。
public static void main(String args[]) {
// Number from 2 to 100
for(int i=2; i < 100; i++) {
if (isPrimeNumber(i)) {
System.out.println(i + " is prime");
}
}
}
现在,让我们看一个未优化的方法isPrimeNumberNotOptimized()
。
private static boolean isPrimeNumberNotOptimized(int i) {
for(int j=2; j <= i/2; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
而且,另一种方法是isPrimeNumberOptimized()
,它使用素数索引进行了优化。
private static boolean isPrimeNumberOptimized(int i) {
for(int j=2; j <= i/j; j++) {
// if it is, then its not prime
if((i%j) == 0) {
return false;
}
}
return true;
}
现在,这两种方法都将正确运行并打印素数。
但是,优化的方法将在第 10 次迭代时确定97
是素数。
并且,未优化的方法将在第 48 次迭代中做出相同的决定。
希望,你现在明白了。
仅供参考:素数指数是我们用于计算的数字。 这样,如果一个数不能在 2 和派生的素数索引之间整除,则它是素数
公共类 PrimeNumber {
//check prime number
public static boolean prime(int number){
boolean isPrime=true;
for(int i=number-1;i>1;i--){
if(number%i==0){
isPrime=false;
System.out.println(i);
break;
}
}
return isPrime;
}
public static boolean getPrimeUsingWhile(int number){
boolean isPrime=true;
Integer temp=number-1;
while (temp>1){
if(number%temp==0){
isPrime=false;
break;
}
temp--;
}
return isPrime;
}
//print primenumber given length
public static List<Integer> prinPrimeList(){
boolean isPrime=true;
List<Integer> list=new ArrayList<>();
int temp=2;
while (list.size()<10){
for(int i=2;i<temp;i++){
if(temp%i==0){
isPrime=false;
break;
}else{
isPrime=true;
}
}
if(isPrime){list.add(temp);}
temp++;
}
return list;
}
public static void main(String arg[]){
System.out.println(prime(3));
System.out.println(getPrimeUsingWhile(5));
System.out.println(Arrays.toString(prinPrimeList().toArray()));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.