【问题标题】:Prime generator in FortranFortran 中的 Prime 生成器
【发布时间】:2011-05-06 07:54:33
【问题描述】:

我只是想稍微熟悉一下 Fortran(因为我可以),所以我编写了这个使用 Eratosthenes 筛生成素数的小程序。这是程序:

program prime
implicit none
integer num_primes, at, found, i
logical is_prime
integer, allocatable, dimension(:) :: primes ! array that will hold the primes
print *, "How many primes would you like to find?"
read (*, *) num_primes
allocate (primes(num_primes))
primes(1) = 2
at = 2
found = 1
do
    is_prime = .true. ! assume prime
    do i = 1, found
        if (modulo(at, primes(i)) == 0) then ! if divisible by any other element
            is_prime = .false.               ! in the array, then not prime.
            at = at + 1
            continue
        end if
    end do
    found = found + 1
    primes(found) = at
    print *, at
    at = at + 1
    if (found == num_primes) then ! stop when all primes are found
        exit
    endif
end do

结束程序主要

运行此程序将显示错误是什么,例如,尝试找到 10 个素数将产生以下数字:3、5、7、11、13、16、17、19、23。显然 16 不是素数。有什么问题?

【问题讨论】:

    标签: fortran primes


    【解决方案1】:

    这不是埃拉托色尼的筛子,它不需要modulo。 这是一种试除法,但是当你找到一个除数时,你将at 增加 1 并从你应该重新开始的下一个素数开始测试。 当您发现 15 可以被 3 整除时,at 会增加到 16,并针对 5、7、11 进行测试,这些当然不是 16 的除数,因此会打印 16。

    我不是 FORTRAN 程序员,但我认为你应该替换这些行

    at = at + 1
    continue
    

    通过

    exit
    

    并执行行

    found = found + 1
    primes(found) = at
    print *, at
    

    仅当 is_prime 为真时。

    【讨论】:

    • 我想要的是一个名为“primes”的数组来包含所有的素数。我最初把 2 放在那里,然后它测试 3,3 不能被 2 整除,所以它是素数,然后是 4。4 可以被 2 整除,所以不是素数,继续……然后 15、15 不能被 2 整除,而是能被 3 整除,所以不是素数。然后 16,它可以被 2 整除,所以不是素数!这是一种埃拉托色尼的 Seive,但它更具有动态性(我猜),我所做的只是用素数进行除法,这就是 Seive 的本质。我虽然不明白你的解释。
    【解决方案2】:

    这是执行 Henrik 建议的工作程序(然后我做了一些格式更改):

    program prime
    implicit none
    
    integer :: num_primes, at, found, i
    logical :: is_prime
    integer, allocatable, dimension(:) :: primes ! array that will hold the primes
    
    print *, "How many primes would you like to find?"
    read(*, *) num_primes
    allocate(primes(num_primes))
    primes(1) = 2
    at = 2
    found = 1
    do
        is_prime = .true. ! assume prime
        do i = 1, found
            if (modulo(at, primes(i)) == 0) then ! if divisible by any other element
                is_prime = .false.               ! in the array, then not prime.
                exit
            end if
        end do
        if (is_prime) then
            found = found + 1
            primes(found) = at
            print *, at
        end if
        at = at + 1
        if (found == num_primes) then ! stop when all primes are found
            exit
        end if
    end do
    end program prime
    

    当你运行它时,你会得到:

     How many primes would you like to find?
    20
               3
               5
               7
              11
              13
              17
              19
              23
              29
              31
              37
              41
              43
              47
              53
              59
              61
              67
              71
    

    primes 数组将包含所有素数。这是你想要的吗?

    【讨论】:

    • 性能可以通过将at 增加 2 而不是 1 以及计算 sqrt(at) 并退出检查大于它的素数来提高。另一件事是它不会打印出第一个素数 2,即使它正确打印出(在本例中)第 20 个素数。
    猜你喜欢
    • 2016-03-05
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    • 2010-11-01
    • 2018-02-11
    • 2023-03-29
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多