Jetzt, wo die Frage geklärt ist, ist hier ein typischer Weg zur Lösung des Problems in Fortran. Es ist nicht der einzig mögliche Weg, aber es ist der allgemeinste. Die Strategie in der routinemäßigen Größenanpassung zur Verdoppelung der alten Größe ist sinnvoll - Sie möchten die Anzahl der Aufrufe minimieren. Der Datensatz im Beispielprogramm ist klein, um den Effekt anzuzeigen, dem ich das Array anfangs sehr klein zugewiesen habe. In Wirklichkeit würden Sie eine relativ große Anfangszuweisung wünschen (sagen wir, mindestens 100).
Beachten Sie die Verwendung einer internen Prozedur, die den Typ Vals_t von seinem Host erbt.
Program Arrays_0
Implicit none
Integer :: i , Read_number , Vig_Position , Vipg_Position , n_iter
Integer , parameter :: Br_gra = 12
Integer , parameter , dimension (Br_gra) :: Vig = [ (i , i = 1 , Br_gra) ]
Integer , parameter , dimension (Br_gra) :: Vipg = [ 0 , 1 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 7 , 7 , 7 ]
Integer :: Result_of_calculation
! Declare a type that will hold one iteration's values
type vals_t
integer Vig_Position
integer Vipg_Position
integer Result_of_calculation
end type vals_t
! Declare an allocatable array to hold the values
! Initial size doesn't matter, but should be close
! to a lower limit of possible sizes
type(vals_t), allocatable :: vals(:)
allocate (vals(2))
Write(*,*)"Enter the number (From 1 to Br_gra):"
Read(*,*) Read_number
Vig_Position = Vig(Read_number)
Vipg_Position = Vipg(Vig_Position)
n_iter = 0
Result_of_calculation = Vig_Position
Do while(Vipg_Position .ne. Vipg(1))
n_iter = n_iter + 1
Vig_Position = Vipg_Position
Result_of_calculation = Result_of_calculation + Vig_Position
Vipg_Position = Vipg(Vig_Position)
! Do we need to make vals bigger?
if (n_iter > size(vals)) call resize(vals)
vals(n_iter) = vals_t(Vig_Position,Vipg_Position,Result_of_calculation)
End Do
Write(*,'(a,1x,i0)')"The number of iteration is:",n_iter
Write(*,'(a,1x,i0)')"The result of calculation is:",Result_of_calculation
! Now vals is an array of size(vals) of the sets of values
! For demonstration, print the size of the array and the values
Write(*,'(a,1x,i0)')"Size of vals is:", size(vals)
Write(*,'(3i7)') vals(1:n_iter)
contains
! Subroutine resize reallocates the array passed to it
! with double the current size, copies the old data to
! the new array, and transfers the allocation to the
! input array
subroutine resize(old_array)
type(vals_t), allocatable, intent(inout) :: old_array(:)
type(vals_t), allocatable :: new_array(:)
! Allocate a new array at double the size
allocate (new_array(2*size(old_array)))
write (*,*) "Allocated new array of size ", size(new_array)
! Copy the data
new_array(1:size(old_array)) = old_array
! Transfer the allocation to old_array
call MOVE_ALLOC (FROM=new_array, TO=old_array)
! new_array is now deallocated
return
end subroutine resize
End Program Arrays_0
Beispielausgabe:
Enter the number (From 1 to Br_gra):
12
Allocated new array of size 4
The number of iteration is: 3
The result of calculation is: 23
Size of vals is: 4
7 3 19
3 1 22
1 0 23
ein Array deklarieren ausreichend großes eine erwartete Anzahl von Iterationen zu halten – agentp
Es gibt keine „erwartete Anzahl von Iterationen“. Diese Nummer ist zu Beginn des Programms unbekannt. –
müssen Sie die Nummer nicht wissen, nur eine obere Grenze. Wenn die Anzahl der Iterationen möglicherweise den Arbeitsspeicher des Computers belastet, sollten Sie die Frage genauer ausführen. – agentp