这是来自Fortran: Open, form='(un)formatted', read的后续问题。我必须创建一个数组,以保存特定条件下的元素数量。
program location
implicit none
interface
function distkm(deglat1,deglon1,deglat2,deglon2)
real :: distkm
real, intent(in) :: deglat1,deglon1,deglat2,deglon2
end function distkm
end interface
integer, parameter :: maxnr = 200000
integer :: nr, i, j, ios
character(len=1) :: junkfornr
real :: start, finish
! My variable declaration
character(len=15), dimension(:), allocatable :: key
real, dimension(:), allocatable :: lat, lon
integer, dimension(:), allocatable :: jobs
! Secondary arrays
integer, dimension(:), allocatable :: jobs_within
integer, dimension(:), allocatable :: sum_jobs
! Determine total number of lines in file
nr=0
open(10, file='location_data2.txt', status='old')
do i=1,maxnr
read(10,*,iostat=ios) junkfornr
if (ios/=0) exit
if (i == maxnr) then
stop
endif
nr = nr + 1
end do
! Create variables: key, lat, lon, jobs
allocate(key(nr))
allocate(lat(nr))
allocate(lon(nr))
allocate(jobs(nr))
allocate(jobs_within(nr))
allocate(sum_jobs(nr))
rewind(10)
do i=1,nr
read(10,*) key(i), lat(i), lon(i), jobs(i)
end do
do i=1,nr
do j=1,nr
if (distkm(lat(i),lon(i),lat(j),lon(j)) <= 0.3) then
jobs_within(j) = jobs(j)
else
jobs_within(j) = 0
end if
end do
sum_jobs(i) = sum(jobs_within)
end do
close(10)
open(20,file='key_sum_jobs_0.3.txt')
do i=1,nr
write(20,100) key(i), sum_jobs(i)
end do
100 format(A15,I6)
end program location
do循环可以为每家公司节省0.3公里范围内的工人总数。在这里,对于每家公司,0.3公里范围内的公司数量各不相同。如何创建一个数组(比如n_neighbor
)来记录每家公司的相邻公司数量?
修改 我相信以下解决了这个问题:
do i=1,nr
n_aux(1:nr) = 0
do j=1,nr
if (distkm(lat(i),lon(i),lat(j),lon(j)) <= 1) then
jobs_within(j) = jobs(j)
n_aux(j) = n_aux(j) + 1
else
jobs_within(j) = 0
end if
end do
write(20,100) key(i), sum(jobs_within), sum(n_aux)
100 format(A15,I8,1X,I3)
end do
我创建了一个整数数组(n_aux
)。然后,unit=20
的输出文本文件保存了三列:(1)公司密钥,(2)0.3公里范围内的工人总数,以及(3)0.3公里范围内的公司数量。
需要思考的事情:
我将n_aux
的所有元素设置为0
循环之前的j
。然后,我抛出1's
条件所在的if
。是否应该有其他方式来表达这种操作,从......动态地将值分配到数组?
答案 0 :(得分:1)
首先,你的代码在双do循环中效率稍低。假设你只有5家公司,那么你的循环将把它们算作
(1,1),(1,2),(1,3),(1,4),(1,5)
(2,1),(2,2),(2,3),(2,4),(2,5)
(3,1),(3,2),(3,3),(3,4),(3,5)
(4,1),(4,2),(4,3),(4,4),(4,5)
(5,1),(5,2),(5,3),(5,4),(5,5)
你可能不想计算从位置1到位置1的距离,因为它是0,因为它是同一家公司。您可能也不想计算(2,1)
,因为您已经为(1,2)
完成了工作。你可以做的是
do i=1,nr
do j=i+1,nr
...
enddo
enddo
但是,如果您确实要计算(1,2)
和 (2,1)
,那么您必须这样做
do i=1,nr
do j=1,nr
if(j == i) cycle
...
enddo
enddo
将跳过j=i
并转到j=i+1
。
至于你的实际问题,我认为你需要的是一维数组,即allocate(n_neighbor(nr))
。如果我们认为相邻位于相同的0.3公里范围内,那么你可以做到
if(distkm(lat(i), lon(i), lat(j), lon(j)) <= 0.3) then
jobs_within(j) = jobs(j)
n_neighbors(j) = n_neighbors(j) + 1
else
jobs_within(j) = 0
endif
我们已初始化n_neighbors=0
。
虽然我不太了解您的问题的背景,但在我看来,jobs_within
的索引应该是i
而不是j
并且您可能希望总结它们,即jobs_within(i) = jobs_within(i) + jobs(j)
。如果不是这种情况,请随意忽略评论。
答案 1 :(得分:0)
我不完全确定你真正想要的是什么,但只是猜测听起来好像你可以写下这样的东西:
n_neighbor(j)=jobs(j)
在你的其他部分。 如果你想要一个更好的答案,请取出你代码中所有不必要的东西。然后用与job_within相同的方式对它进行求和。