Fortran:未知的数组大小(计算数组的元素)

时间:2013-11-14 09:46:45

标签: arrays fortran

这是来自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。是否应该有其他方式来表达这种操作,从......动态地将值分配到数组?

2 个答案:

答案 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相同的方式对它进行求和。