[英]Java function to find prime number not working
The function takes in an integer N. The function must print all prime numbers from 2 to N (including N, if N is itself a prime number). 该函数采用整数N.该函数必须打印从2到N的所有素数(包括N,如果N本身是素数)。
I have the function and it runs, but it is skipping some prime numbers and even including some even numbers like 8. I can't seem to find the bug that is causing this. 我有功能,它运行,但它正在跳过一些素数,甚至包括一些像8这样的偶数。我似乎无法找到造成这种情况的错误。
Here's what my code looks like: 这是我的代码的样子:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PrimeNumbers {
List <Integer> primeList = new ArrayList<Integer>();
public ArrayList<Integer> findPrimes(int n){
if(n == 2){
primeList.add(n);
}
else{
//should I have i=i+2 instead of i++ to move faster?
//If so, by doing this, it causes weird and different
//output when running
for(int i=2; i<=n; i++){
if(n%i != 0){
primeList.add(i);
}
}
}
return (ArrayList<Integer>) primeList;
}
public static void main(String[] args) {
PrimeNumbers pn = new PrimeNumbers();
System.out.println(pn.findPrimes(15));
}
}
Your logic is entirely backwards. 你的逻辑是完全倒退的。 You can only say a number is prime if you've tested ALL possible divisors. 如果你测试了所有可能的除数,你只能说一个数字是素数。 You're currently adding ANY number which has a non-zero remainder, which is BACKWARDS. 您当前正在添加具有非零余数的任何数字,即BACKWARDS。 A non-zero remainder means it was NOT evenly divisible, meaning it's NOT a multiple of the factor you're testing, eg 非零余数意味着它不是可分割的,这意味着它不是您正在测试的因子的倍数,例如
8 % 3 -> 2
2 != 0 -> true
therefore 8 is prime
You can only do your .add()
call AFTER you've finished the loop and no tests came back true: 您只能在完成循环之后执行.add()
调用,并且没有测试返回true:
is_prime = true; // assume prime
for(i = 2; i <= n; i++) {
if (n % 2 == 0) { // no remainder, even divisible, therefore NOT primt
is_prime = false;
break; // abort the loop, no point in testing more
}
}
And yes, you can boost efficiency somewhat by starting your tests at 3 and jumping by 2. Since 2
is the only even prime, it is literally impossible for any OTHER even number to be prime, because 2 is a divisor of all even numbers. 是的,你可以通过在3开始你的测试并且跳过2来提高效率。由于2
是唯一的偶数素数,所以任何其他偶数都不可能是素数,因为2是所有偶数的除数。 So test 3,5,7,9,etc... 所以测试3,5,7,9等...
eg 例如
test if `n` is even and `!= 2` - if so, then it's NOT prime
run 3,5,7,... loop to test everything else
Your logic for finding prime numbers is incorrect. 您找到素数的逻辑是不正确的。
Right now, what your code does is: 1. Iterate on all the integers up to N 2. Find any integer that N can't be divided by, and add them to the list. 现在,你的代码所做的是:1。迭代所有N到2的整数。找到N不能除以的任何整数,并将它们添加到列表中。 This has nothing to do with prime numbers. 这与素数无关。
Instead, your code should do something like: 1. Iterate on all the integers up to N 2. For each of these integers (let's say M), run a sub-loop iterating on all integers below it, and checking if none of those integers can divide M. If the sub-loop finishes without finding a divider of M, add M to the list - it's a prime number (can't be divided by any integer except 1 and itself). 相反,你的代码应该做类似的事情:1。迭代所有整数,最多N 2.对于每个整数(假设是M),运行一个子循环迭代它下面的所有整数,并检查是否都没有整数可以除以M.如果子循环完成而没有找到M的除法器,则将M添加到列表中 - 它是素数(不能除以1和它本身之外的任何整数)。
Simple code for checking if a number (2 or above) is prime: 用于检查数字(2或以上)是否为素数的简单代码:
public boolean isPrime(int num)
{
for (int i = 2; i < num; ++i)
{
if (num % i == 0)
{
return false;
}
}
return true;
}
There are many optimisations for this and it's a world by itself. 对此有很多优化,它本身就是一个世界。
All you've done is find the not factors of n
. 你所做的就是找到n
的不是因素。 You test if each number leading up to it is a factor of n
by adding it if n % i != 0
. 如果n % i != 0
,则通过添加它来测试导致它的每个数是n
的因子。
What you need to do is iterate from 2 to n, and for each of those numbers, test if it's prime. 你需要做的是从2迭代到n,对于每个数字,测试它是否是素数。 You will need two loops. 你需要两个循环。 I suggest creating a method to determine prime numbers, and I guess your current method is find as it is. 我建议创建一个确定素数的方法,我猜你当前的方法是找不到的。 Just replace if (n % i != 0)
with if(isPrime(i))
用if(isPrime(i))
替换if (n % i != 0)
if(isPrime(i))
public static boolean isPrime(long n) {
// eliminate the simple cases
if (n < 2) {
return false;
} else if (n == 2) {
return true;
}
// only test up until the square root of that number
for (int i = 2; i < Math.pow(n, 0.5) + 1; i++) {
if (n % i == 0) {
return false; // found a factor, it's not prime
}
}
return true; // hasn't found a factor and returned false, so it's prime
}
And then in your current code: 然后在您当前的代码中:
for(int i=2; i<=n; i++){
if(n%i != 0){
primeList.add(i);
}
}
Just change if(n%i != 0){
to if(isPrime(i))
只需改变if(n%i != 0){
to if(isPrime(i))
So it would be this: 所以它会是这样的:
for(int i=2; i<=n; i++){
if(isPrime(i)) {
primeList.add(i);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.