简体   繁体   中英

Prime number finder

So I am trying to make a prime number finder, and to save computation time I want it to abort the forloop once it finds a divisor which is not 1 or the number itself. Now the function works, but it completely ignores my ifstatement. What am I doing wrong?

def prime(number):
    oldnum = number
    factor = 1
    while number > 1:
        factor += 1
        while number % factor == 0:
            if 1< factor < oldnum:
                return 0 # is not prime
                print("yay")
                break
            number //= factor
    return 1 #prime!

Just use Erathostenes's sieve . It's an old and proven method to find primes :)

Your code never reaches the line return 1 (which should be return True , by the way) because

  • your break statement would only break out of the inner while loop
  • that break statement isn't ever reached because you return 0 before that.

Your inner while loop should be an if , anyway (since you're not actually doing anything that requires looping).

If you change that (and remove the unreachable code), it "works" (besides the erronenous result of prime(1) being True ), it's a very inefficient way of finding prime numbers.

def prime(number):
    oldnum = number
    factor = 1
    while number > 1:
        factor += 1
        if number % factor == 0:
            if 1 < factor < oldnum:
                return False # is not prime
            number //= factor
    return True # is prime!

只需对性能改进发表一点评论,您只需要检查from 2 to sqrt(num)的因素,而不是从2 to num

What about this function ?


import math
def prime(number): if number == 1: return 1 for i in range(2, int(math.sqrt(number)) + 1): if number % i == 0: return 0 return 1

Since your ultimate objective is to find primes effectively, and others have answered the coding problem very well, I'll go into a bit more detail than other answers on how to do it more efficiently.

The Sieve of Eratosthenes is the fastest way of finding primes up to 10 million or so. But you seem to want to determine if just some given number n is prime or not.

To check if a number n is prime you only need to check if it is divisible by primes which are less than or equal to sqrt(n) . So using this method, if you want your function to handle numbers up to 100 million, you'll only need to prepare a list of all the primes up to 10000 (1229 primes), which will take a negligible amount of time.

If you're interested I can put in my sieve implementation here, but I'm guessing you're solving this problem for your own amusement, so I'll leave you to it.

As Tim points out you need the inner while to be an if. Something like this will work (but be horribly inefficient)

def prime(number):
    oldnum = sqrt(number)
    factor = 1
    while factor <= oldnum:
        factor += 1
        if number % factor == 0 :
            return 0 # is not prime
    return 1 #prime!

I agree to above answers.. A number x is said to be prime if it has only factors 1 and itself ... The ideal method will be to check whether there are any factors from 2 to ceiling function(sqrt(x))... where the ceiling function (n) refers to smallest integer greater than or equal to n.

The function in C would look like...

// function returns.. { -> -1 for neither prime nor composite.. -> 0 for composite numbers.. -> 1 for prime numbers.. }

.....................................

 boolean isPrime(int n){

     if(n<=1){
       return -1;
     }else{
      for(int i=2;i<Math.sqrt(n);i++){
        if(n%i==0)
         return 1;
      }
      return 0;
     }
    }

Try this (implementation of Sieve of Eratosthenes ).

def squares_till(n):
    def square_add(i,n):
        j = i**2
        while j < n:
            yield j
            j = j + i
    A = [True]*n
    A[0] = A[1] = False
    for i in range(2,int(n**0.5)):
        if A[i]:
            for j in square_add(i,n):
                A[j] = False
    return [num for num in range(n) if A[num]]

I do not know your concern, but I think it works well

def is_prime(number):
if number > 2:
    i = 2
    while number > i:
        if number % i == 0:
            return False
            break
        else:
            i=i+1
    return True

elif number == 2:
    return True
else:
    return False

I believe that, this is very efficient implementation. It may be further improved by incorporation Primality test (O(1) implementation).

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>

using namespace std;

void printN(const vector<int> container, int count, ostream& out=cout, const string& delim=", ") {
    for(int i=0; i<count; ++i)
        out << container[i] << delim;
    out << endl;
}

void printNPrimes(int count) {
    static const int FIRST_PRIME = 2;
    static vector<int> primes(1, FIRST_PRIME);
    static int rangeEnd = 3;

    if(primes.size() >= count) {
        printN(primes, count);
        return;
    }

    int remainingPrimeNumbers = count - primes.size();

    while(remainingPrimeNumbers) {
        bool is_prime = true;
        for(int prime : primes) {
            if(rangeEnd % prime == 0) {
                is_prime = false;
                break;
            }
        }

        if(is_prime) {
            primes.push_back(rangeEnd);
            --remainingPrimeNumbers;
        }

        ++rangeEnd;
    }

    printN(primes, count);
}

int main(int argc, const char *argv[])
{
    if(argc < 2) {
        cout << "usage: rund <count>";
        return -1;
    }

    int count = atoi(argv[1]);
    printNPrimes(count);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM