当我运行此代码时,即使只是算出第10个质数(而不是1000),我也会得到歪斜/中止的输出-is_composite变量的所有"非质数"标题,我的test_num都给了我质数和复合数, 而且我的prime_count已关闭
开发人员共享使用功能和数学导入的一些答案-我们尚未涵盖。 我不是在寻求最有效的答案; 我只是试图编写可行的python代码以了解循环的基础。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# test a prime by diving number by previous sequence of number(s) (% == 0). Do this by
# counting up from 1 all the way to 1000.
test_num = 2 #these are the numbers that are being tested for primality
is_composite = 'not prime' # will be counted by prime_count
prime_count = 0 #count the number of primes
while (prime_count<10): #counts number primes and make sures that loop stops after the 1000th prime (here: I am just running it to the tenth for quick testing)
test_num = test_num + 1 # starts with two, tested for primality and counted if so
x = test_num - 1 #denominator for prime equation
while (x>2):
if test_num%(x) == 0:
is_composite = 'not prime'
else:
prime_count = prime_count + 1
x = x - 1
print is_composite
print test_num
print prime_count
具体是什么不起作用?
什么都没有回来/发生
您的算法很慢,请使用数论对其进行优化。具体来说,仅检查小于或等于当前数平方根的质数。
主题外:代码中的某些注释正确,另一些则显而易见:while x > 2: # runs while x is greater than 2不言而喻。一般而言:评论原因,而不是原因。
谢谢阿德里亚诺-从现在开始我会牢记这一点:评论
这是功课。我们都知道,这正是MIT的"计算机科学与程序设计导论"第一次作业的第一个问题集的第一个问题。
我没有看到任何打印语句或其他输出,因此什么也没有返回或(明显)发生。
这听起来很像projecteuler
您和我对"大"素数有不同的想法。对我来说,一个大质数足够大,以至于所有小于该候选质数的质数都将比测试该候选质数的机器(集群?)所占用的内存(硬盘空间?)更多。对我来说,最初大约2 ^ 40个素数很小
我是使用big重命名该问题的人。
DGM-这是家庭作业-但对于OpenCourse Ware-无等级。只是想学习。
@zkidd:问题不在于家庭作业的原因,而在于您的处理方式:如果您遇到这个问题并说"我已经做了这个,那个我在这里遇到了这个问题",这表明您确实被困扰了努力。一开始对一些代码说"我有麻烦",这些代码起初甚至没有打印语句,这表明他们很努力。
试试这个unreachable2027.wordpress.com/2012/10/02/
请参阅MIT提供的有关您的作业的提示。我在下面引用它们:
初始化一些状态变量
生成所有大于1的(奇数)个整数作为质数的候选项
对于每个候选整数,测试其是否为质数
3.1。一种简单的方法是测试是否其他任何大于1的整数将余数为0的候选数均分。为此,可以使用模块化算术,例如,表达式a%b在将整数a除以整数b之后返回余数。
3.2。您可能会考虑需要将哪些整数作为除数进行检查-当然您不需要超出要检查的候选数,但是您可以停止检查多少时间?
如果候选对象是质数,请打印一些信息,以便您知道计算中的位置,并更新状态变量
达到适当的结束条件时停止。在制定此条件时,请不要忘记您的程序没有生成第一个素数(2)。
它可能看起来像这样:
1
2
3
4
5
6
7
8def primes(n):
# http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
""" Returns a list of primes < n"""
sieve = [True] * n
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i]:
sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
return [2] + [i for i in xrange(3,n,2) if sieve[i]]
昨天我经历了这些提示,但仍然遇到问题。因此,我的职位。
即使我仔细阅读了这些提示并重新观看了演讲,但我仍在问这个问题,这让我感到非常糟糕。
您可能想看看更有效的解决方案以获得Python方式。
首先,从对素数检查算法的模糊描述中,您似乎正在检查每个数字,直至要检验素数的数字。但是,实际上,您只需要测试该数字的平方根即可。进一步的优化是删除除2以外的所有偶数(您可以通过从1增加2并分别测试2来实现),最终得到:
1
2
3
4def isprime(test):
if test == 2: return True
if test < 2 or test % 2 == 0: return False
return not any(test % i == 0 for i in range(3, int(sqrt(test)) + 1, 2))
然后,您要做的就是从2个以上的数字进行迭代,以检查它们是否为质数,如果是则将其加到计数器中。当达到1000时,停止并输出传??递给isprime函数的数字。
当然,还有其他更有效的方法,我个人更喜欢Atkin筛。但这取决于您来实现,我的算法将为您服务。
编辑:我注意到您的评论"什么都没有返回/正在发生",这是由于算法效率低下所致,如果等待足够长的时间,您将得到答案。但是,我确实注意到您提供的代码中没有打印语句,我希望您所运行的代码中包含该语句。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18from math import sqrt
def isprime(test):
if test == 2: return True
if test < 2 or test % 2 == 0: return False
return not any(test % i == 0 for i in range(3, int(sqrt(test)) + 1, 2))
test_num = 2
prime_count = 1
while (prime_count< 1000):
test_num = test_num + 1
if (isprime(test_num)):
prime_count += 1
print test_num
您不需要编写单独的isprime函数。您可以检查递增的序列,因此可以检查先前的质数作为当前除数的除数。
例如看rwh_primes(n)。
我的只是简单的替代算法,它实现相同结果的效率较低。如果zkidd想研究它,我提供了另一种Atkin筛子。
Thnx炒锅和njak32-我要看的一切。但是,现在我正在运行程序,它看起来像是进入" 49"并停止。我在正在使用的打印语句中添加了内容。但是素数确实可以达到1000。你们中的任何一个都可以检查上述内容是否正确?
从1开始prime_count,因为在当前方法中您没有计数2。
我为我的答案添加了一个可行的解决方案。
谢谢njak32!您的答案使用math.import和def ---我们还没有介绍,但是我会用您的输出来检查我的(效率较低)输出
这是我为C ++编写的代码。但是心态必须相同。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// This code was written by Mert Ener
#include
#include
#include
private: System::Void button1_Click_1(System::Object^ sender,
System::EventArgs^ e) {
using namespace std;
UInt64 cloc = clock();
long m = 1;
long k = long::Parse(textBox1->Text)-2; // The text you entered
std::vector p(1,2); // for the nth prime
for( long n = 0; n <= k; n++ ) {
m += 2;
for( long l = 1; l <= n; l++ ) {
if (m % p[l] == 0) {
m += 2;
l=0;}}
p.push_back(m);}
textBox2->Text = p[k+1].ToString(); // The textbox for the result.
MessageBox::Show("It took me" + (clock() - cloc).ToString()
+" milliseconds to find your prime.");}
下面的代码生成一百万个素数的列表。
使用该列表,您可以以相当快的方式测试小于1万亿的素数。
对于10到12位数的质数,这运行时间非常快。
1
2
3
4
5
6
7
8
9
10import math
from itertools import islice
# number of primes below the square root of x
# works well when x is large (x > 20 and much larger)
numchecks = lambda x: int((math.sqrt(x))/(math.log(math.sqrt(x)) - 1.084)) + 1
primes = [2,3,5]
primes = primes + [x for x in range(7, 48, 2) if all((x%y for y in islice( primes, 1, int(math.sqrt(x)) )))]
primes = primes + [x for x in range(49, 2400, 2) if all((x%y for y in islice( primes, 1, numchecks(x) )))]
primes = primes + [x for x in range(2401, 1000000, 2) if all((x%y for y in islice( primes, 1, numchecks(x) )))]
您可以通过扩展上面的过程来增加保存的素数的数量,但是该程序将花费很长时间(但是只能执行一次)。
在您的代码中,可以使用以下命令测试" test_num"是否为质数...
1
2
3
4
5
6
7
8
9test_num = 23527631
if test_num<100:
checks = int(math.sqrt(test_num))
else:
checks = numchecks(test_num)
isPrime = all(test_num%x for x in islice(primes, 0, checks))
print 'The number is', 'prime' if isPrime else 'not prime'
print 'Tested in', checks, 'divisions'
为什么不isPrime = all(test_num % x for x in it.islice(primes, 0, checks))。 islice可能会过大,但是all是进入此处的唯一方法;)
@Aaron:使其变得更快的方法!谢谢。