我是计算机科学和编程的新手。我正在编写一个免费的在线课程,其中一个任务是编写一个能够生成第1000个素数的程序。
仅供参考,这是在Python 2.5.4中
以下是我在此论坛上从另一个帖子中复制(并编辑了一点点)的原始代码:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="columns" id="content">Ricky Thomas Ponting, AO (born 19 December 1974), nicknamed Punter, is an Australian cricketer, and former captain of the Australia national cricket team between 2004 and 2011 in Test cricket and 2002 and 2011 in One Day International cricket. He is a specialist right-handed batsman, slips and close catching fielder, as well as a very occasional bowler. He represents the Tasmanian Tigers in Australian domestic cricket, the Hobart Hurricanes in the Big Bash League, and played in the Indian Premier League with the Kolkata Knight Riders in 2008. He is widely considered by many to be one of the best batsmen of the modern era, along with Sachin Tendulkar of India and Brian Lara of the West Indies. On 1 December 2006, he reached the highest rating achieved by a Test batsman in the last 50 years. Ponting made his first-class debut for Tasmania in November 1992, when just 17 years and 337 days old, becoming the youngest Tasmanian to play in a Sheffield Shield match. However, he had to wait until 1995 before making his One Day International (ODI) debut, during a quadrangular tournament in New Zealand in a match against South Africa. His Test debut followed shortly after, when selected for the first Test of the 1995 home series against Sri Lanka in Perth, in which he scored 96. He lost his place in the national team several times in the period before early-1999, due to lack of form and discipline, before becoming One Day International captain in early-2002 and Test captain in early-2004. After being involved in over 160 Tests and 370 ODIs, Ponting is Australia's leading run-scorer in Test and ODI cricket. He is one of only four players (along with Sachin Tendulkar, Rahul Dravid and Jacques Kallis) in history to have scored 13,000 Test runs. Statistically, he is one of the most successful captains of all time, with 48 victories in 77 Tests between 2004 and 31 December 2010, while as a player he is also the only cricketer in history to be involved in 100 Test victories.[1] On 29 November 2012 Ponting announced his retirement from Test cricket, the day before he would play in the Perth Test against South Africa. This was his 168th and last Test appearance,[2] equalling the Australian record held by Steve Waugh.[3][4] Ricky Ponting retired on 3 December 2012 with a Test batting average of 51.85.[5] He continued to play cricket around the world. In February 2013 it was announced that he would be captaining the Mumbai Indians team in the Indian Premier League.[6] and in March 2013 he was announced as the first international franchise player for the Caribbean Premier League.[7] Later that month it was revealed by Ponting that this would be his last season playing cricket, as at the end of the competition he would be retiring from all forms of the game.[8] In his final first class innings for Surrey against Notts he hit an unbeaten 169 bringing up a total of 82 first class 100s in an illustrious county career.
<p>
Candlestick Park hosted the Giants from 1960 to 1999 and the 49ers from 1971 until 2013.
The San </p>
<p>
testingThe San </p>
</div>
<div class="columns" id="content2"></div>
<div class="columns"id="content3"></div>
<div class="columns" id="content4"></div>
<div class="columns" id="content5"></div>
<div class="columns" id="content6"></div>
<div class="columns" id="content7"></div>
<div class="columns" id="content8"></div>
<div class="columns" id="content9"></div>
但是,我认为通过重写isprime(n)函数可以使程序更快,如下所示:
def isprime(n):
if n<2:
return False
else:
for i in range(2,(n/2+1)):
if n%i==0:
return False
else:
return True
def nthprime(n):
x=[]
j=2
while len(x)<n:
if (isprime(j)) == True:
x.append(j)
j =j+1
return(x[n-1])
print nthprime(1000)
这样,当只检查n是否可以被奇数整数整除时(通过代码中的这一点,我们已经知道n是奇数,因此不能被任何偶数整数整除)。
我认为以这种方式重写它会使程序工作速度提高两倍(因为它只检查了一半的数字),但似乎需要花费相同的时间,甚至更长的时间,而不是之前的情况。
另外,有没有办法重写第二个代码块来摆脱:
def isprime(n):# First the primality test
i=1
if n<2:
return False
if (n!=2 and (n/2*2==n)):
return False
if n==3:
return True
if n==5:
return True
else:
while i <= (n/2+1):
i+=2
if n%i==0:
return False
else:
return True
我包含的唯一原因是因为我意识到我的算法正在生成&#34; false&#34;对于3和5,即使它们是素数。
答案 0 :(得分:3)
我看到你的优化是什么,但我认为你实施的逻辑并不是你想要的。相反,可以考虑使用其他方法来减少必须检查的数字。
我建议的第一个是立即排除偶数:
def isprime(n):
if n < 2 or n % 2 == 0:
return False
# ...
您需要检查的另一个重要方面是在优化失败时进行因素检查。你不需要一直走到n / 2
;您需要担心的最大因素是sqrt(n)
(一旦您通过了根n
,您就会开始检查您已经检查过的因素,例如,如果您已经检查过检查n = 6
,检查2后,您已经检查过3)。这是相应的优化:
def isprime(n):
# ...
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
总之,这里是新isprime
(编辑:提供评论提示):
def isprime(n):
if n == 2: return True
if n % 2 == 0: return False
for i in xrange(3, int(n ** 0.5) + 1, 2):
if n % i == 0: return False
return True
计算nthprime(5000)
,这2次优化花了我的时间从 8.497 秒到 0.108 秒。
编辑:demo