【发布时间】:2019-11-14 21:15:18
【问题描述】:
我试图在排序数组中找到包含值 i 的最小索引。如果此 i 值不存在,我希望返回 -1。我正在使用二进制搜索递归子例程。问题是我无法真正停止这种递归,我得到了很多答案(一个正确,其余错误)。有时我会收到一个名为“分段错误:11”的错误,但我并没有真正得到任何结果。
我试图删除这个调用 random_number,因为我的主程序中已经有一个排序数组,但它不起作用。
program main
implicit none
integer, allocatable :: A(:)
real :: MAX_VALUE
integer :: i,j,n,s, low, high
real :: x
N= 10 !size of table
MAX_VALUE = 10
allocate(A(n))
s = 5 ! searched value
low = 1 ! lower limit
high = n ! highest limit
!generate random table of numbers (from 0 to 1000)
call Random_Seed
do i=1, N
call Random_Number(x) !returns random x >= 0 and <1
A(i)= anint(MAX_VALUE*x)
end do
call bubble(n,a)
print *,' '
write(*,10) (a(i),i=1,N)
10 format(10i6)
call bsearch(A,n,s,low,high)
deallocate(A)
end program main
排序子程序:
subroutine sort(p,q)
implicit none
integer(kind=4), intent(inout) :: p, q
integer(kind=4) :: temp
if (p>q) then
temp = p
p = q
q = temp
end if
return
end subroutine sort
气泡子程序:
subroutine bubble(n,arr)
implicit none
integer(kind=4), intent(inout) :: n
integer(kind=4), intent(inout) :: arr(n)
integer(kind=4) :: sorted(n)
integer :: i,j
do i=1, n
do j=n, i+1, -1
call sort(arr(j-1), arr(j))
end do
end do
return
end subroutine bubble
recursive subroutine bsearch(b,n,i,low,high)
implicit none
integer(kind=4) :: b(n)
integer(kind=4) :: low, high
integer(kind=4) :: i,j,x,idx,n
real(kind=4) :: r
idx = -1
call random_Number(r)
x = low + anint((high - low)*r)
if (b(x).lt.i) then
low = x + 1
call bsearch(b,n,i,low,high)
else if (b(x).gt.i) then
high = x - 1
call bsearch(b,n,i,low,high)
else
do j = low, high
if (b(j).eq.i) then
idx = j
exit
end if
end do
end if
! Stop if high = low
if (low.eq.high) then
return
end if
print*, i, 'found at index ', idx
return
end subroutine bsearch
目标是获得与我的线性搜索相同的结果。但我得到了这些答案中的任何一个。
排序表:
1 1 2 4 5 5 6 7 8 10
5 found at index 5
5 found at index -1
5 found at index -1
或者如果没有找到该值
2 2 3 4 4 6 6 7 8 8
Segmentation fault: 11
【问题讨论】:
-
请使用标签fortran,您会得到更多关注。
-
请用它制作一个完整的可编译程序。另外我怀疑
bsearch例程中缺少一些声明,请明确添加它们(还有implicit none,所以没有一个被遗忘。删除r时,您使用哪个值random_number。 -
最好为您的子例程提供显式接口。将它们放在一个模块中或将它们放在内部(在
contains之后和end program之前)。这将启用一些编译器检查。此外,当您遇到类似的崩溃时,您总是 应该启用编译器检查,例如gfortran -Wall -fcheck=all -g -fbacktrace或您的编译器的等效项。这非常重要。 -
您当前的代码无法编译。它给出了许多编译时错误。您必须显示实际代码,minimal reproducible example。另外,关于模块的问题,如果没有完整的代码和完整的错误信息,我也无话可说。
-
确实如此。我在分配之前放置了 N=5,现在编译时它不会给我一个一般错误。 'Segmentation fault: 11' 错误只会在找不到该值时出现。我添加了 bsearch 子程序。
标签: recursion fortran binary-search