在Julia中使用for循环打印范围内的素数

在Julia中使用for循环打印范围内的素数,julia,Julia,我正在学习Julia语法,我对一般的编码是新手。 我正在寻找一种使用for循环和if语句打印给定范围内所有素数的方法。 (像这样的东西) 使用显式检查候选因子的方法,下面的情况如何?我在代码之前或之后用注释注释,而不是逐字逐句: # 2 is a special case, just print it println(2) for num in 3:2:100 # step sizes of 2 starting from 3, only need to check odd numbers

我正在学习Julia语法,我对一般的编码是新手。 我正在寻找一种使用for循环和if语句打印给定范围内所有素数的方法。 (像这样的东西)


使用显式检查候选因子的方法,下面的情况如何?我在代码之前或之后用注释注释,而不是逐字逐句:

# 2 is a special case, just print it
println(2)

for num in 3:2:100  # step sizes of 2 starting from 3, only need to check odd numbers now
    prime_candidate = true  # consider everything prime until proven otherwise
    for i in 3:2:floor(Int,sqrt(num))  # no need to check 1, num itself, or even numbers
        if (num % i) == 0   # divisible by a smaller number?
            prime_candidate = false # mark it not prime...
            break   # ...and we're outta here!
        end
    end
    if prime_candidate  # if the boolean hasn't been flipped by now, it's prime
        println(num)
    end
end

感谢Oscar Smith建议将检查范围更改为
sqrt(num)
。假设
num
可被
i
整除。然后它必须有一个辅助因子
j
,以便
i*j=num
。如果
i
j
都大于
sqrt(num)
,那么它们的乘积将大于
num
,因此
i
j
中的一个必须为≤ <代码>sqrt(num)。因此,如果您在到达
sqrt(num)
时未找到因子,则
num
没有整数因子,必须为素数,以便停止搜索。

如果您感兴趣,这里有一个基于以下条件的替代解决方案:

请注意,这与蛮力方法的实际代码行数几乎相同(去掉注释后)。这两种方法都能产生相同的结果,但这个版本的速度要快得多——2.1s比67s在我的笔记本电脑上生成664579个素数,最高可达10_000_000


补遗 我对朱莉娅来说是个新手,在玩这个游戏的过程中我一直在学习。这导致了下面的版本,我将条件循环替换为
&&
foreach
。我删除了注释,以强调所需的代码是多么少:

UPPERLIMIT = 100

is_prime = [(i % 2) > 0 for i in 1:UPPERLIMIT]
is_prime[2] = true  # 2 is the exception, an even prime

for num in 3:2:floor(Int,sqrt(UPPERLIMIT))
    is_prime[num] && foreach(i -> is_prime[i] = false, num*num:2*num:UPPERLIMIT)
end

foreach(i -> is_prime[i] && println(i), 2:UPPERLIMIT)

此变体不仅涉及更少的代码,而且运行速度更快—1.41s比2.1s生成的素数最多可达10M。

素数包有一个使用Miller-Rabin素数测试()的函数

所以你可以做:

import Primes

for num in 1:100
  Primes.isprime(num) ? println(num) : nothing
end
如果您只需要一组在某个范围内为素数的数字,可以使用以下方法:

filter(Primes.isprime, 1:100)
如果您还没有Primes软件包,可以这样添加:

import Pkg
Pkg.add("Primes")

我唯一要做的更改是将3:2中的I的
(num-1)
更改为3:2中的I的
:floor(Int,sqrt(num))
。这一个改变将使它在二次上更快。@OscarSmith很好的回答。我不明白为什么使用“平方根”而不是“num-1”也能工作。可能是数学上的原因,我为自己的无知道歉。我可以问更多的情况吗?无论如何,我真的很喜欢这种方法。我认为替换
Primes.isprime(num)会更惯用吗?println(num):使用
Primes时不使用任何东西。isprime(num)和&println(num)
注意,这个答案将比primesife慢。实际上,您可以加快速度。您只需要在
num*num
处开始划掉数字,而不是
3*num
。这是因为
num
的所有较小倍数都被划掉了。
filter(Primes.isprime, 1:100)
import Pkg
Pkg.add("Primes")