私はPythonプログラミングを学ぼうとしていますが、これはかなり新しいです。
100から100までの一連の素数の印刷に問題がありました。私のコードの何が問題なのかわかりません。
これが私が書いたものです。素数の代わりにすべての奇数を出力します:
for num in range(1,101):
for i in range(2,num):
if (num%i==0):
break
else:
print(num)
break
2からn-1までのすべての数値を確認する必要があります(実際にはsqrt(n)ですが、OK、nにしてください)。 n
がいずれかの数値で割り切れる場合、素数ではありません。数が素数の場合、それを印刷します。
for num in range(2,101):
prime = True
for i in range(2,num):
if (num%i==0):
prime = False
if prime:
print num
同じものをもっと短く、よりPython的に書くことができます:
for num in range(2,101):
if all(num%i!=0 for i in range(2,num)):
print num
すでに述べたように、2からn-1ではなく、2からsqrt(n)の除数をチェックする方が良いでしょう:
import math
for num in range(2,101):
if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)):
print num
101のような小さな数値の場合、それは重要ではありませんが、10 ** 8の場合、違いは本当に大きくなります。
チェックする範囲を2増やして、奇数のみをチェックすることで、さらに改善できます。そのようです:
import math
print 2
for num in range(3,101,2):
if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1)):
print num
編集済み:
最初のループでは奇数が選択されているため、2番目のループでは偶数でチェックする必要がないため、「i」値は3で始まり2でスキップされます。
import math
print 2
for num in range(3,101,2):
if all(num%i!=0 for i in range(3,int(math.sqrt(num))+1, 2)):
print num
2000年以上前にギリシャの数学者エラトステネスによって発明されたより良いアプローチは、試行分割の代わりに、複数の素数を繰り返しキャストしてふるいにかけることです。
2から最大の素数nまでのすべての数値のリストを作成することから始めます。その後、最小の非交差数を繰り返し取得し、その倍数をすべて取り消します。交差していない数は素数です。
たとえば、30未満の数を考えます。最初に2が素数として識別され、次に4、6、8、10、12、14、16、18、20、22、24、26、28、および30が消されます。次の3は素数として識別され、6、9、12、15、18、21、24、27、および30は消されます。次の素数は5なので、10、15、20、25、および30が消されます。等々。残りの数は素数です:2、3、5、7、11、13、17、19、23、および29。
def primes(n):
sieve = [True] * (n+1)
for p in range(2, n+1):
if (sieve[p]):
print p
for i in range(p, n+1, p):
sieve[i] = False
ふるいの最適化されたバージョンは2を別々に処理し、奇数のみをふるいにかけます。また、現在の素数の平方より小さいすべての合成はより小さい素数で消されるため、内側のループはpではなくp ^ 2で開始でき、外側のループはnの平方根で停止できます。 最適化されたバージョン はそのままにしておきます。
break
は現在のループを終了します。したがって、2で割り切れるかどうかを確認するだけで、すべての奇数が得られます。
for num in range(2,101):
for i in range(2,num):
if (num%i==0):
break
else:
print(num)
とはいえ、これよりもpythonで素数を見つけるより良い方法があります。
for num in range(2,101):
if is_prime(num):
print(num)
def is_prime(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
私は、最良のソリューションを想定せずにテストすることを提案しています。以下は、@ igor-chubinと@ user448810の両方でサンプルの簡単なクラスを作成するために行った変更です。まず最初に、それはすべて素晴らしい情報だと言わせてください、皆さんありがとう。しかし、@ user448810の巧妙なソリューションを認めなければなりません。これは、(テストしたものの中で)最速です。よろしくお願いします!すべての例で、nとして100万(1,000,000)の値を使用します。
コードを試してみてください。
がんばろう!
方法1 Igor Chubinによる説明:
def primes_method1(n):
out = list()
for num in range(1, n+1):
prime = True
for i in range(2, num):
if (num % i == 0):
prime = False
if prime:
out.append(num)
return out
ベンチマーク: 272+秒以上
方法2 Igor Chubinによる説明:
def primes_method2(n):
out = list()
for num in range(1, n+1):
if all(num % i != 0 for i in range(2, num)):
out.append(num)
return out
ベンチマーク: 73.3420000076秒
方法 Igor Chubinによる説明:
def primes_method3(n):
out = list()
for num in range(1, n+1):
if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)):
out.append(num)
return out
ベンチマーク: 11.3580000401秒
方法4 Igor Chubinによる説明:
def primes_method4(n):
out = list()
out.append(2)
for num in range(3, n+1, 2):
if all(num % i != 0 for i in range(2, int(num**.5 ) + 1)):
out.append(num)
return out
ベンチマーク: 8.7009999752秒
方法5 user448810で説明されているように(これは非常に賢いと思った):
def primes_method5(n):
out = list()
sieve = [True] * (n+1)
for p in range(2, n+1):
if (sieve[p]):
out.append(p)
for i in range(p, n+1, p):
sieve[i] = False
return out
ベンチマーク: 1.12000012398秒
注:上記のソリューション5(user448810によって提案された)は、最速かつ正直で静かな創造的で賢いものであることが判明しました。大好きです。みんなありがとう!!
編集:ああ、ところで、値の平方根の数学ライブラリをインポートする必要があるとは感じませんでした。等価なのは(n **。5)です。それ以外の場合は、他の多くを編集せずに、値をクラスに格納して出力配列をクラスから返すようにしました。また、結果をファイルに保存する方が冗長よりもおそらく効率的であり、一度に1つだけの場合はメモリを大幅に節約できますが、ディスク書き込みのために少し時間がかかります。しかし、常に改善の余地があると思います。だから、うまくいけば、コードは理にかなっている。
A Python 1'st N素数を返すプログラム関数モジュール:
def get_primes(count):
"""
Return the 1st count prime integers.
"""
result = []
x=2
while len(result) in range(count):
i=2
flag=0
for i in range(2,x):
if x%i == 0:
flag+=1
break
i=i+1
if flag == 0:
result.append(x)
x+=1
pass
return result
上記の問題を解決する最良の方法は、「ミラーラビン素数テスト」アルゴリズムを使用することです。確率的アプローチを使用して、数値が素数かどうかを調べます。そして、これは私がこれまで出会った中で最も効率的なアルゴリズムです。
python同じものの実装を以下に示します。
def miller_rabin(n, k):
# Implementation uses the Miller-Rabin Primality Test
# The optimal number of rounds for this test is 40
# See http://stackoverflow.com/questions/6325576/how-many-iterations-of-rabin-miller-should-i-use-for-cryptographic-safe-primes
# for justification
# If number is even, it's a composite number
if n == 2:
return True
if n % 2 == 0:
return False
r, s = 0, n - 1
while s % 2 == 0:
r += 1
s //= 2
for _ in xrange(k):
a = random.randrange(2, n - 1)
x = pow(a, s, n)
if x == 1 or x == n - 1:
continue
for _ in xrange(r - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
あまり手間をかけずに素数をエントリ番号にリストする私の方法は、素数の合計で素数でない任意の数を取得できるというプロパティを使用することです。
したがって、エントリ番号をその下のすべての素数で除算し、それらのいずれによっても割り切れない場合、素数があることがわかります。
もちろん素数を取得するより高速な方法はまだありますが、これはすでに非常にうまく機能しています。特に、エントリ番号を任意の数で割るのではなく、素数だけをその数まで分割しているためです。
このコードを使用して、コンピューターで管理し、4秒以内に最大100 000までのすべての素数をリストしました。
import time as t
start = t.clock()
primes = [2,3,5,7]
for num in xrange(3,100000,2):
if all(num%x != 0 for x in primes):
primes.append(num)
print primes
print t.clock() - start
print sum(primes)
min=int(input("min:"))
max=int(input("max:"))
for num in range(min,max):
for x in range(2,num):
if(num%x==0 and num!=1):
break
else:
print(num,"is prime")
break
a=int(input('enter the lower no.'))
b=int(input('enter the higher no.'))
print("Prime numbers between",a,"and",b,"are:")
for num in range(a,b):
if num>1:
for i in range(2,num):
if (num%i)==0:
break
else:
print(num)
これが、RECURSIVE関数の素数であるかどうかをチェックするシンプルで直感的なバージョンです。 :)(MITクラスの宿題として行った)pythonでは、1900まで非常に高速に実行されます。1900を超えて試行すると、興味深いエラーが表示されます:)(コンピューターで管理できる数字の数を確認したいですか?)
def is_prime(n, div=2):
if div> n/2.0: return True
if n% div == 0:
return False
else:
div+=1
return is_prime(n,div)
#The program:
until = 1000
for i in range(until):
if is_prime(i):
print i
もちろん...再帰的な関数が好きなら、この小さなコードを辞書でアップグレードしてパフォーマンスを大幅に向上させ、そのおかしなエラーを回避できます。 MEMORY統合を使用したレベル1の簡単なアップグレードを次に示します。
import datetime
def is_prime(n, div=2):
global primelist
if div> n/2.0: return True
if div < primelist[0]:
div = primelist[0]
for x in primelist:
if x ==0 or x==1: continue
if n % x == 0:
return False
if n% div == 0:
return False
else:
div+=1
return is_prime(n,div)
now = datetime.datetime.now()
print 'time and date:',now
until = 100000
primelist=[]
for i in range(until):
if is_prime(i):
primelist.insert(0,i)
print "There are", len(primelist),"prime numbers, until", until
print primelist[0:100], "..."
finish = datetime.datetime.now()
print "It took your computer", finish - now , " to calculate it"
結果は次のとおりです。見つかった最後の100個の素数を印刷しました。
日時:2013-10-15 13:32:11.674448
100000まで9594の素数があります
[99991、99989、99971、99961、99929、99923、99907、99901、99881、99877、99871、99859、99839、99833、99829、99823、99817、99809、99793、99787、99767、99761、99733、99721、99719 、99713、99709、99707、99689、99679、99667、99661、99643、99623、99611、99607、99581、99577、99571、99563、99559、99551、99529、99527、99523、99497、99487、99469、99439、99431 、99409、99401、99397、99391、99377、99371、99367、99349、99347、99317、99289、99277、99259、99257、99251、99241、99233、99223、99191、99181、99173、99149、99139、99137、99133 、99131、99119、99109、99103、99089、99083、99079、99053、99041、99023、99017、99013、98999、98993、98981、98963、98953、98947、98939、98929、98927、98911、98909、98899、98897 ] ...
コンピューターの計算には0:00:40.871083がかかりました
したがって、i7ラップトップで計算するのに40秒かかりました。 :)
n = int(raw_input('Enter the integer range to find prime no :'))
p = 2
while p<n:
i = p
cnt = 0
while i>1:
if p%i == 0:
cnt+=1
i-=1
if cnt == 1:
print "%s is Prime Number"%p
else:
print "%s is Not Prime Number"%p
p+=1
sympyライブラリを使用して素数のリストを作成できます
import sympy
lower=int(input("lower value:")) #let it be 30
upper=int(input("upper value:")) #let it be 60
l=list(sympy.primerange(lower,upper+1)) #[31,37,41,43,47,53,59]
print(l)
初心者が素数を取得するための最も簡単なロジックは次のとおりです。
p=[]
for n in range(2,50):
for k in range(2,50):
if n%k ==0 and n !=k:
break
else:
for t in p:
if n%t ==0:
break
else:
p.append(n)
print p
これは、数値が素数かどうかをチェックするために作成したサンプルプログラムです。
def is_prime(x):
y=0
if x<=1:
return False
Elif x == 2:
return True
Elif x%2==0:
return False
else:
root = int(x**.5)+2
for i in xrange (2,root):
if x%i==0:
return False
y=1
if y==0:
return True
これはどう?私がこれを使用したすべての提案を読んでください:
prime=[2]+[num for num in xrange(3,m+1,2) if all(num%i!=0 for i in range(2,int(math.sqrt(num))+1))]
最大1000000の素数
root@nfs:/pywork# time python prime.py
78498
実際の0m6.600s
ユーザー0m6.532s
sys 0m0.036s
def prime_number(a):
yes=[]
for i in range (2,100):
if (i==2 or i==3 or i==5 or i==7) or (i%2!=0 and i%3!=0 and i%5!=0 and i%7!=0 and i%(i**(float(0.5)))!=0):
yes=yes+[i]
print (yes)
def fac(n):
res = []
for i in range(1,n+1):
if n%i == 0:
res.append(i)
def prime(n):
return(fac(n) == [1,n])
def prime_list(n):
pri_list = []
for i in range(1,n+1):
if prime(i)
pri_list.append(i)
return(pri_list)
f=0
sum=0
for i in range(1,101):
for j in range(1,i+1):
if(i%j==0):
f=f+1
if(f==2):
sum=sum+i
print i
f=0
print sum
素数の省略の最速で最高の実装:
def PrimeRanges2(a, b):
arr = range(a, b+1)
up = int(math.sqrt(b)) + 1
for d in range(2, up):
arr = omit_multi(arr, d)
Igor Chubinの答えは改善できます。 Xが素数であるかどうかをテストする場合、アルゴリズムはXの平方根までのすべての数をチェックする必要はありません。sqrt(X)までの素数をチェックするだけです。したがって、作成時に素数のリストを参照する方が効率的です。以下の関数は、bの下にすべての素数のリストを出力します。これは、いくつかの理由(たとえば、素数の数<bを知りたい場合)のリストとして便利です。素数をチェックするだけで、より大きな数で時間を節約できます(10,000程度と比較してください。違いは明白です)。
from math import sqrt
def lp(b)
primes = [2]
for c in range(3,b):
e = round(sqrt(c)) + 1
for d in primes:
if d <= e and c%d == 0:
break
else:
primes.extend([c])
return primes
受け入れられた答えに加えて、リストを使用して素数を保存し、生成後にそれらを印刷することにより、さらなる最適化を実現できます。
import math
Primes_Upto = 101
Primes = [2]
for num in range(3,Primes_Upto,2):
if all(num%i!=0 for i in Primes):
Primes.append(num)
for i in Primes:
print i
# computes first n prime numbers
def primes(n=1):
from math import sqrt
count = 1
plist = [2]
c = 3
if n <= 0 :
return "Error : integer n not >= 0"
while (count <= n - 1): # n - 1 since 2 is already in plist
pivot = int(sqrt(c))
for i in plist:
if i > pivot : # check for primae factors 'till sqrt c
count+= 1
plist.append(c)
break
Elif c % i == 0 :
break # not prime, no need to iterate anymore
else :
continue
c += 2 # skipping even numbers
return plist
ループの終了が早すぎます。 forループの本体のすべての可能性をテストし、ブレークしない場合、数値は素数になります。素数ではないため、2から始める必要があります。
for num in xrange(2, 101):
for i in range(2,num):
if not num % i:
break
else:
print num
より高速なソリューションでは、テストする数値のルート以下の素数で除算しようとします。これは、すでに見つけたすべての素数を記憶することで実現できます。さらに、奇数(2を除く)のみをテストする必要があります。結果のアルゴリズムをジェネレーターに入れると、コンテナーに素数を保存したり、単に印刷したりするために使用できます。
def primes(limit):
if limit > 1:
primes_found = [(2, 4)]
yield 2
for n in xrange(3, limit + 1, 2):
for p, ps in primes_found:
if ps > n:
primes_found.append((n, n * n))
yield n
break
else:
if not n % p:
break
for i in primes(101):
print i
ご覧の通り、平方根を計算する必要はありません。各素数の平方を保存し、各除数をこの数と比較する方が高速です。
検索時間を短縮するためにスペースを使用する別のアプローチを次に示します。これは最速かもしれません。
import math
def primes(n):
if n < 2:
return []
numbers = [0]*(n+1)
primes = [2]
# Mark all odd numbers as maybe prime, leave evens marked composite.
for i in xrange(3, n+1, 2):
numbers[i] = 1
sqn = int(math.sqrt(n))
# Starting with 3, look at each odd number.
for i in xrange(3, len(numbers), 2):
# Skip if composite.
if numbers[i] == 0:
continue
# Number is prime. Would have been marked as composite if there were
# any smaller prime factors already examined.
primes.append(i)
if i > sqn:
# All remaining odd numbers not marked composite must be prime.
primes.extend([i for i in xrange(i+2, len(numbers), 2)
if numbers[i]])
break
# Mark all multiples of the prime as composite. Check odd multiples.
for r in xrange(i*i, len(numbers), i*2):
numbers[r] = 0
return primes
n = 1000000
p = primes(n)
print "Found", len(p), "primes <=", n
フィルター機能を使用します。
l=range(1,101)
for i in range(2,10): # for i in range(x,y), here y should be around or <= sqrt(101)
l = filter(lambda x: x==i or x%i, l)
print l
for num in range(1,101):
prime = True
for i in range(2,num/2):
if (num%i==0):
prime = False
if prime:
print num
Igorに触発され、リストを作成するコードブロックを作成しました。
def prime_number():
for num in range(2, 101):
prime = True
for i in range(2, num):
if (num % i == 0):
prime = False
if prime and num not in num_list:
num_list.append(num)
else:
pass
return num_list
num_list = []
prime_number()
print(num_list)
これを解決するより簡単で効率的な方法は、以前に見つかったすべての素数を保存し、次の数がより小さい素数の倍数であるかどうかを確認することです。
n = 1000
primes = [2]
for i in range(3, n, 2):
if not any(i % prime == 0 for prime in primes):
primes.append(i)
print(primes)
any
は短絡関数であることに注意してください。言い換えると、真実の値が見つかるとすぐにループを中断します。
Pythonを使用してn個の素数を出力します。
num = input('get the value:')
for i in range(2,num+1):
count = 0
for j in range(2,i):
if i%j != 0:
count += 1
if count == i-2:
print i,