我正在解决这个问题:
通过列出前六个素数:2,3,5,7,11和13,我们可以看到第6个素数是13。 什么是10 001主数?
def checkPrime(x):
facs = 0
for i in range(1,x):
if x%i==0:
facs = facs + 1
if facs == 2:
return True
else :
return False
i = 1
noPrime = 0
done = False
while(done==False):
i = i + 1
print "i = {0} and noPrime={1}".format(i,noPrime)
if checkPrime(i)==True:
noPrime = noPrime + 1
if noPrime==10001 :
print i
done=True
但这需要花费很多时间 我怎样才能加快速度?
答案 0 :(得分:5)
使用素性测试的方法:
def isPrime(n):
if n == 2: return True
if n % 2 == 0 or n < 2: return False
for i in range(3, int(n**0.5)+1, 2):
if n % i == 0: return False
return True
if __name__ == "__main__":
n = count = 1
while count < 10001:
n += 2
if isPrime(n): count += 1
print n
在0.2秒内运行。这个问题无关紧要,但正如其他人所说,筛子更有效率。
答案 1 :(得分:4)
您可以使用prime number theorem来估算您需要走多远的距离。 (估计程序中数组p的大小)。 pi(n)
,小于n
的素数的数量渐近n%^.n
(n
除以ln n
)。对于第10001个素数,等式为10001=n%^.n
,求解n
得到n
在1.1e5和1.2e5之间。
因此,您可以缩小选中值的范围并仅检查范围的数字。这种技术减少了程序的运行时间。
答案 2 :(得分:2)
您不需要使用Sieve of Eratosthenes (虽然您将来会遇到问题)。找到10001素数相对较快。
注意事项:
下面的剧透 - 假设你已经解决了问题,但这只需要很长时间
C#中的示例(抱歉,不知道python):
class Program
{
static bool IsPrime(int value)
{
if (value == 2) return true;
if (value % 2 == 0) return false;
// Test for divisors up to the square root of "value", increment by 2.
for (int i = 3; i <= Math.Sqrt(value); i += 2)
{
if (value % i == 0)
return false;
}
return true;
}
static void Main(string[] args)
{
int primeCount = 1; // #2
// Test only odd numbers.
for (int i = 3; ; i += 2)
{
if (IsPrime(i))
{
primeCount++;
if (primeCount == 10001)
{
Console.WriteLine(i.ToString());
break;
}
}
}
Console.ReadLine();
}
}
答案 3 :(得分:2)
由于其他人都在发布他们的解决方案,我认为我会对简单划分方法做一些明显的改进:
def is_prime(nr):
if nr < 2: return false
if nr < 4: return true
if nr % 2 == 0: return false
if nr < 9: return true
if nr % 3 == 0: return false
for i in range(5, int(nr**0.5) + 1, 6):
if number % i == 0: return false
if number % (i + 2) == 0: return false
return true
通过摆脱一个不必要的模运算,这改进了简单的解决方案。