Fortran 95 中的二进制搜索

Posted

技术标签:

【中文标题】Fortran 95 中的二进制搜索【英文标题】:Binary Search in Fortran 95 【发布时间】:2021-05-10 07:14:28 【问题描述】:

我尝试在 Fortran 95 中使用递归函数实现二进制搜索。

我的错误信息是:/usr/bin/timeout: the monitoring command dumped core

有人知道我该如何解决这个问题吗?

这个小程序的返回值应该是2。

另外:如何扩展我的代码以返回数组“ar”的位置编号以知道我可以在哪里添加我的新元素(即“2.9”)?如果是 2.9,它应该返回 2。另一个例子,如果我使用 7.3 而不是 2.9,它应该返回 6(在数组“ar”的 7.0 和 8.0 之间)。

program h
   real, dimension(7) :: ar
   integer :: s
   real :: outp
   ar = (/2.0, 3.0, 4.0, 5.0, 7.0, 8.0, 9.0/)
   s = sizeof(ar)
   outp = findAr(ar, 1, s, 3.0)
   print*, outp
end program h

recursive function findAr(ar, l, r, x) result(a)
        real, dimension(size(ar)), intent(in)  :: ar
        integer, intent(in) :: l, r
        real, intent(in) :: x
        integer :: midd
        real :: a
        if (r >= 1) then
            midd = l + (r - 1) / 2
            if (ar(midd) == x) then
                a = midd
            else if (ar(midd) > x) then
                a = findAr(ar, l, midd - 1, x)
                else
                a = findAr(ar, midd + 1, r, x)
            end if
        end if
end function findAr

【问题讨论】:

real, dimension(size(ar)), intent(in) :: ar 试图说'将 ar 声明为一个数组,其大小由其大小决定'。对可怜的编译器说这不是一件好事。你想发生什么。我猜你的意思是dimension(:) 甚至dimension(*) 但如果你能澄清一下会很有帮助。 如果Dimension(:)你还需要一个范围内的接口,我认为你也需要递归例程——所以把所有子程序都放在模块中,然后你就不用担心了关于当前的规则是什么。 如果使用递归函数,则需要显式接口。 当然你在 Fortran 90-2008 中做过。鉴于截至 2018 年,所有例程默认情况下都是递归的,我不确定要求是否已放宽。但在调用任何例程时,无论是否递归使用,在范围内都有一个接口绝对是最佳实践 【参考方案1】:

编译器错误可以按照 cmets 对您的问题的指定解决。


关于您的第二个问题:如何扩展您的代码以在数组元素之间搜索值。可以以相同的方式询问数组之外​​的值(例如,小于其最小值)。

以下代码未使用递归函数,也不是您的代码的扩展。 您应该记住,不必要的函数调用会产生一些开销,并可能导致性能损失。

module bin_search_m
  implicit none
contains
  function bin_search(x, x1) result(i)
    !! find index of nearest value in sorted array
    real,              intent(in) :: x(:)
      !! sorted array
    real,              intent(in) :: x1
      !! value to find
    integer                       :: i
      !! return array index

    integer :: i0, i1

    ! starting interval is the whole array
    i0 = 1
    i1 = size(x)

    ! test if x1 is outside of interval [x(1), x(end)]
    if (x1 <= x(i0)) then
      i = i0
      return
    end if
    if (x1 >= x(i1)) then
      i = i1
      return
    end if

    ! binary search
    do while (i1 > (i0 + 1))
      i = (i1 + i0) / 2
      if      (x(i) < x1) then
        i0 = i
      else if (x(i) > x1) then
        i1 = i
      else
        return
      end if
    end do

    ! pick index of value that is closer
    i = merge(i0, i1, ((2 * x1) < (x(i0) + x(i1))))
  end function
end module

【讨论】:

嗨,杰克,非常感谢您的帮助。我尝试按以下方式实现您的代码,并且在使其运行时遇到了一些麻烦。我真的不知道为什么它不起作用。你能看看我的代码并再次帮助我吗? 程序 hello 隐式非实数,维度(7) :: ar 实数 :: val 整数 :: outp ar = (/2.d0, 3.d0, 4.d0, 5.d0, 7 .d0, 8.d0, 9.d0/) val = 3.d0 outp = findInAr(ar, val) print*, outp end program hello 整数函数 findInAr(x, x1) 隐式非实数,intent(in) :: x(:) 实数,intent(in) :: x1 整数 :: i0, i1, a i0 = 1 i1 = size(x) if (x1 = x(i1)) then findInAr = i1 return end if do while (i1 > (i0 + 1) ) a = (i1 + i0) / 2 if (x(a) x1) then i1 = 1 else return end if end do findInAr = a end function跨度> 在此处附加您的问题,甚至更好:创建一个新问题。评论部分不是讨论代码的好地方。我的回答有帮助吗?

以上是关于Fortran 95 中的二进制搜索的主要内容,如果未能解决你的问题,请参考以下文章

java 95.独特的二进制搜索树II(#)。java

java 95.独特的二进制搜索树II(#)。java

java 95.独特的二进制搜索树II(#)。java

java 95.独特的二进制搜索树II(#)。java

java 95.独特的二进制搜索树II(#)。java

java 95.独特的二进制搜索树II(#)。java