我正在使用Schaum的Fortran 77编程大纲,并且有一个关于使用包围值组方法的二进制搜索的示例。首先,这是代码:
INTEGER X(100)
INTEGER RANGE
INTEGER START , FINISH
PRINT *, 'Number of values ?'
READ *, N
DO 10 I = 1, N
READ *, X(I)
END DO
PRINT *, 'Enter Value'
READ *, VAL
START = 1
FINISH = N
RANGE = FINISH - START
MID = (START + FINISH) /2
DO WHILE( X(MID) .NE. VAL .AND. RANGE .NE. 0)
IF (VAL .GT. X(MID))THEN
START = MID
ELSE
FINISH = MID
END IF
RANGE = FINISH - START
MID = (START + FINISH)/2
END DO
IF( X(MID) .NE. VAL) THEN
PRINT *, VAL, 'NOT FOUND'
ELSE
PRINT *, 'VALUE AT' , MID
END IF
END
问题是,当我输入7个值数组时,如
2 | 9 | 11 | 23 | 49 | 55 | 66
例如,当
时搜索66MID = 5
,下一个循环的新MID变为6。但是当它为6时,它无法在下一个循环中增加,因为
MID =(START + FINISH)/ 2 =(6 + 7)/ 2 = 6
当然应该是7。
它仍然是6.而我的程序当然永远不会给我一个输出。 我该怎么办?
答案 0 :(得分:10)
这只是一个错字,或者当他们从C版本翻译并且不得不改变索引时,有人会感到困惑。
循环中的键不变量是,如果它在列表中,则值必须落在数组中从索引开始到结束的某个位置(包括端点)。但是一旦你排除了中期,它应该被列入清单。但它不在这里,所以列表总是太长,你遇到了你看到的问题。
正确的版本设置从中间+ 1开始,或者完成到中间1,以排除中间。修正后的代码,用Fortran 90风格编写:
program binarysearch
implicit none
integer, allocatable, dimension(:) :: x
integer :: range, start, finish, mid
integer :: i, n, val
print *, 'Number of values ?'
read *, N
allocate( x(N) )
do i = 1, n
READ *, x(i)
end do
print *, 'Enter Value'
read *, VAL
start = 1
finish = N
range = finish - start
mid = (start + finish) /2
do while( x(mid) /= val .and. range > 0)
if (val > x(mid)) then
start = mid + 1
else
finish = mid - 1
end if
range = finish - start
mid = (start + finish)/2
end do
if( x(mid) /= val) then
print *, val, 'NOT FOUND'
else
print *, 'VALUE AT' , mid
end if
deallocate( x )
end program binarysearch