web-dev-qa-db-ja.com

Python素数チェッカー

私は入力された数値を取得し、それが素数であるかどうかを確認するプログラムを作成しようとしています。数字が実際に素数であれば、これまでに作成したコードは完全に機能します。数が素数でない場合、奇妙に振る舞います。コードの問題点を誰かが教えてくれるかどうか疑問に思っていました。

a=2
num=13
while num > a :
  if num%a==0 & a!=num:
    print('not prime')
    a=a+1
  else:
    print('prime')
    a=(num)+1

24が入力されたときに得られる結果は次のとおりです。

すべての偶数の素数ではなくすべての奇数の報告素数のエラーをどのように修正しますか

29
Chris

数値が素数でないことがわかったら、繰り返しを停止する必要があります。 primeが見つかったら、breakを追加して、whileループを終了します。

コードを最小限の変更のみで機能させる:

a=2
num=13
while num > a :
  if num%a==0 & a!=num:
    print('not prime')
    break
  i += 1
else: # loop not exited via break
  print('prime')

アルゴリズムは次と同等です:

for a in range(a, num):
    if a % num == 0:
        print('not prime')
        break
else: # loop not exited via break
    print('prime')

関数にスローすると、breakとfor-elseを省くことができます:

def is_prime(n):
    for i in range(3, n):
        if n % i == 0:
            return False
    return True

このような素数のブルートフォースを行う場合でも、nの平方根まで反復するだけです。また、2の後の偶数のテストをスキップできます。

これらの提案で:

import math
def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    for i in range(3, int(math.sqrt(n)) + 1, 2):
        if n % i == 0:
            return False
    return True

このコードは、01、および負の数を適切に処理しないことに注意してください。

allとジェネレーター式を使用してforループを置き換えることにより、これをより簡単にします。

import math
def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
63
def isprime(n):
    '''check if integer n is a prime'''

    # make sure n is a positive integer
    n = abs(int(n))

    # 0 and 1 are not primes
    if n < 2:
        return False

    # 2 is the only even prime number
    if n == 2: 
        return True    

    # all other even numbers are not primes
    if not n & 1: 
        return False

    # range starts with 3 and only needs to go up 
    # the square root of n for all odd numbers
    for x in range(3, int(n**0.5) + 1, 2):
        if n % x == 0:
            return False

    return True

から取得:

http://www.daniweb.com/software-development/python/code/216880/check-if-a-number-is-a-prime-number-python

20
Destructor
def is_prime(n):
    return all(n%j for j in xrange(2, int(n**0.5)+1)) and n>1
12

コードに関する2つの主な問題は次のとおりです。

  1. 素数ではない数を指定した後、それが素数でないことを既に知っている場合でも、残りの除数のチェックを続けます。これにより、「素数ではない」を印刷した後に「素数」を印刷することになります。ヒント:「break」ステートメントを使用します。
  2. "prime" insideループを出力しているため、チェックする必要のあるすべての除数をチェックする前に、数素数を指定します。したがって、テストされる数に均等に入らない除数ごとに1回、「プライム」を複数回取得します。ヒント:ループでelse句を使用して、ループが中断せずに終了する場合にのみ「prime」を出力します。

かなり重大な非効率なカップル:

  1. 既に見つけた素数で、それらで割るだけの数を追跡する必要があります。すでに2で割ったのに、なぜ4で割るのですか?数値が4で割り切れる場合、2で割り切れるので、すでにキャッチされているはずなので、4で割る必要はありません。
  2. テストする数値の平方根までテストする必要があります。それより大きい係数にはそれより小さい数値を掛ける必要があり、それは大きな数値に到達するまでに既にテストされているからです。
10
kindall

この例では、reduce()を使用していますが、速度が遅くなります。

def makepnl(pnl, n):
    for p in pnl:
        if n % p == 0:
            return pnl
    pnl.append(n)
    return pnl

def isprime(n):
    return True if n == reduce(makepnl, range(3, n + 1, 2), [2])[-1] else False

for i in range(20):
    print i, isprime(i)

Skin Of Atkin を使用し、上記より高速です:

def atkin(limit):
    if limit > 2:
        yield 2
    if limit > 3:
        yield 3

    import math
    is_prime = [False] * (limit + 1)

    for x in range(1,int(math.sqrt(limit))+1):
        for y in range(1,int(math.sqrt(limit))+1):
            n = 4*x**2 + y**2

            if n<=limit and (n%12==1 or n%12==5):
                # print "1st if"                                                                                                                    
                is_prime[n] = not is_prime[n]
            n = 3*x**2+y**2
            if n<= limit and n%12==7:
                # print "Second if"                                                                                                                 
                is_prime[n] = not is_prime[n]
            n = 3*x**2 - y**2
            if x>y and n<=limit and n%12==11:
                # print "third if"                                                                                                                  
                is_prime[n] = not is_prime[n]

    for n in range(5,int(math.sqrt(limit))):
        if is_prime[n]:
            for k in range(n**2,limit+1,n**2):
                is_prime[k] = False

    for n in range(5,limit):
        if is_prime[n]: yield n

def isprime(n):
    r = list(atkin(n+1))
    if not r: return False
    return True if n == r[-1] else False

for i in range(20):
    print i, isprime(i)
3
Keisuke URAGO

ここの初心者なので、私がそうであるかどうか私に知らせてください、しかし、私はこのようにします:

def prime(n):
    count = 0
    for i in range(1, (n+1)): 
         if n % i == 0: 
             count += 1
    if count > 2:
        print "Not a prime"
    else:
        print "A prime"
2
dasdachs

あなたの問題は、すでに「決心した」と思っていても、ループが実行され続けることです。 a=a+1の後にbreak行を追加する必要があります

2
Ofir Israel

数値が(素数ではなく)複合であると判断したら、作業は完了です。 breakでループを終了できます。

while num > a :
  if num%a==0 & a!=num:
    print('not prime')
    break          # not going to update a, going to quit instead
  else:
    print('prime')
    a=(num)+1

また、Pythonの一部の構造に慣れてみるとよいでしょう。あなたのループは、私の意見ではまだ読みやすいワンライナーに短縮できます。

any(num % a == 0 for a in range(2, num))
1
Prashant Kumar

これは、要因を追跡するという点でわずかな違いです。

def prime(a):
    list=[]
    x=2
    b=True

    while x<a:
        if a%x==0:
            b=False
            list.append(x)
        x+=1

    if b==False:
        print "Not Prime"
        print list
    else:
        print "Prime"
0
saegarde
a=input("Enter number:")

def isprime(): 

    total=0
    factors=(1,a)# The only factors of a number
    pfactors=range(1,a+1) #considering all possible factors


    if a==1 or a==0:# One and Zero are not prime numbers
        print "%d is NOT prime"%a


    Elif a==2: # Two is the only even prime number
        print "%d is  prime"%a


    Elif a%2==0:#Any even number is not prime except two
        print "%d is NOT prime"%a  



    else:#a number is prime if its multiples are 1 and itself 
         #The sum of the number that return zero moduli should be equal to the "only" factors
        for number in pfactors: 
            if (a%number)==0: 
                total+=number
        if total!=sum(factors):
            print "%d is NOT prime"%a 
        else:
             print "%d is  prime"%a
isprime()
0
Francis Mujjuni

素数チェック。

def is_prime(x):
    if x < 2:
        return False
    else:
        if x == 2:
            return True
        else:
            for i in range(2, x):
                if x % i == 0:
                    return False
            return True
x = int(raw_input("enter a prime number"))
print is_prime(x)
0
Sakti Rout

これは仕事をするでしょう:

number=int(raw_input("Enter a number to see if its prime:"))
if number <= 1:
    print "number is not prime"
else:
    a=2
    check = True
    while a != number:
        if number%a == 0:
            print "Number is not prime"
            check = False
            break
        a+=1
    if check == True:
        print "Number is prime" 
0
CodingOcean
max=int(input("Find primes upto what numbers?"))
primeList=[]
for x in range(2,max+1):
    isPrime=True
    for y in range(2,int(x**0.5)+1) :
        if x%y==0:
            isPrime=False
            break

    if isPrime:
        primeList.append(x)
print(primeList)
0
Datta Munde