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 中的二进制搜索的主要内容,如果未能解决你的问题,请参考以下文章