La ayuda necesita una matriz asignable en FORTRAN
-
03-07-2019 - |
Pregunta
Realmente estoy teniendo problemas con la matriz asignable.
Tengo que copiar toda la información de un archivo en una matriz asignable. El archivo es así:
3
3 5
2 1
4 0
3 es el número de puntos los otros seis números muestran puntos en la gráfica en forma (x, y). Entonces (3,5), (2, 1), (4,0) son los puntos. Pero tengo problemas para hacer estos números como un par.
Traté de codificar, y aquí está mi codificación:
PROGRAM practice
IMPLICIT NONE
INTEGER :: astat, ioStatus
INTEGER :: x, y
INTEGER :: num, code1, code2, code3, code4, code5, code6
! num shows number of location. in this case 3
! code 1 to 6 shows x and y variable. and code1 and 2 have to be paired.
! as well as this, code 3 and 4, code 5 and 6 have to be paired
! Declare TYPE
! set 1 to 3 show pair of (x, y)
TYPE Location
INTEGER :: set1, set2, set3
INTEGER :: num_locations
END TYPE
! Array ()
! for number of locations to visit
TYPE(Location), DIMENSION(:) :: numLocationArray(1000)
! allocatable array
! For locations
TYPE(Location), DIMENSION(:, :) :: LocationArray
ALLOCATABLE :: LocationArray
! allocate LocationArray
ALLOCATE(LocationArray(x, y), STAT = astat)
IF (astat < 0) STOP "allocate failed"
! open input file to copy info into array
OPEN (UNIT = 10, File ="input.txt", STATUS = "OLD", ACTION = "READ", &
IOSTAT = ioStatus)
IF (ioStatus < 0) STOP "open failed"
! format of the file
100 FORMAT (I1, /, 2I2, /, 2I2, / 2I2)
! Do loop to set table
DO x = 0, size(LocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = ioStatus) num, code1, code2, &
code3, code4, code5, code6
! check whether program read file correctly (option)
PRINT *, num, code1, code2, code3, code4, code5, code6
IF (x == code1) THEN
DO y = 0, size(LocationArray), 1
IF (y == code2) THEN
LocationArray%set1 = LocationArray(x, y)
! check whether copied correctly
PRINT *, LocationArray(x, y)
PRINT *, LocationArray%set1
END IF
END DO
END IF
END DO
! ==============
! execution part
! ==============
! instructions:
! use pointer to do excecution
! read allocatable array above
! do excecution (distance) ** do not forget to go back to the original place (0,0)
! ** do not forget to try every single possible way
! when get total distance, do distance times 2 and figure out cost
! print all info (cost, distance, and steps)
! (example of output)
! The minimum cost is 36
! The distance travelled is 18
! Step 1: Start at ( 0, 0)
! Step 2: Goes to ( 2, 1)
! Step 3: Goes to ( 3, 5)
! Step 4: Goes to ( 4, 0)
! Step 5: Ends at ( 0, 0)
END PROGRAM
Este programa no funciona ... Tengo un error:
LocationArray%set1 = LocationArray(x, y)
Error: Can't convert TYPE(location) to INTEGER(4) at (1)
Me cansé de descubrir este error, pero no pude ¿Alguien tiene algún consejo o sugerencia sobre mi codificación?
Perdona mi inglés, soy japonés.
Si alguien tiene preguntas sobre mi pregunta (quiero decir, necesita más explicación), hágamelo saber.
Gracias. Uka
Solución
En la definición del tipo Location
, usted ha dicho que set1, set2 y set3 son variables enteras, luego intenta asignarle una matriz. Creo que lo que quieres, ya que son pares, es que set1, set2 y set3 sean una matriz entera de tamaño 2.
¿Qué sucede si cambia el tipo de Ubicación
para que sea:
TYPE Location
INTEGER, DIMENSION(2) :: set1, set2, set3
INTEGER :: num_locations
END TYPE
Además, el bucle para leer los datos no tiene sentido para mí. Creo que lo escribiría como (tenga en cuenta que los arreglos en Fortran están basados ??en 1 por defecto, no en cero como en C):
DO x = 1, size(numLocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = ioStatus) num, code1, code2, &
code3, code4, code5, code6
! check whether program read file correctly (option)
PRINT *, num, code1, code2, code3, code4, code5, code6
numLocationArray(x)%num_locations = num
numLocationArray(x)%set1(0) = code1
numLocationArray(x)%set1(1) = code2
numLocationArray(x)%set2(0) = code3
numLocationArray(x)%set2(1) = code4
numLocationArray(x)%set3(0) = code5
numLocationArray(x)%set3(1) = code6
END DO
Obviamente, también deberá hacer algo para detectar y manejar la condición del final del archivo.
Si la cantidad de ubicaciones es realmente variable, entonces deberías hacer algo como:
TYPE Coordinate
INTEGER :: x
INTEGER :: y
END TYPE
TYPE Locations
TYPE(Coordinate), DIMENSION(:), ALLOCATABLE :: location
INTEGER :: num_locations
END TYPE
TYPE(Location), DIMENSION(:) :: numLocationArray(1000)
! open input file to copy info into array
OPEN (UNIT = 10, File ="input.txt", STATUS = "OLD", ACTION = "READ", &
IOSTAT = ioStatus)
IF (ioStatus < 0) STOP "open failed"
! format of the file
100 FORMAT (I1 )
200 FORMAT (2I2)
DO n = 1, size(numLocationArray), 1
READ (UNIT = 10, FMT = 100, IOSTAT = iostatus) num
numLocationArray(n)%num_locations = num
ALLOCATE (numLocationArray(n)%locations(num), STAT = astat)
if (astat < 0) STOP 'allocate failed'
DO l = 1, num, 1
READ (UNIT = 10, FMT = 200, IOSTAT = iostatus) x, y
numLocationArray(n)%locations(l)%x = x
numLocationArray(n)%locations(l)%y = y
END DO
END DO
Otros consejos
Parece que está intentando dar a un entero el valor de dos enteros. Es algo como lo que intentas hacer = (o var = 5,5).