Pergunta

Eu realmente estou tendo problemas com variedade ALLOCATABLE.

Eu tenho que copiar todas as informações de um arquivo em conjunto allocatable. O arquivo é assim:

3 
3 5 
2 1 
4 0

3 é o número de pontos outros mostra pontos de seis números no gráfico em (x, y) forma. Então, (3,5), (2, 1), (4,0) são os pontos. Mas eu tenho problema de fazer esses números como um par.

Eu tentei código, e aqui é a minha codificação:

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 não funciona ... Eu tenho um erro:

LocationArray%set1 = LocationArray(x, y)
Error: Can't convert TYPE(location) to INTEGER(4) at (1)

Eu cansei de descobrir este erro, mas eu não podia Alguém qualquer conselho ou sugestão sobre a minha codificação?

Perdoe meu Inglês, eu sou japonês.

Se alguém tem dúvidas sobre minha pergunta (eu quero dizer necessidade de mais explicação), por favor me avise.

Obrigado. Uka

Foi útil?

Solução

Na definição do tipo Location, você disse que set1, set2, e set3 são inteiro variáveis, então você tentar atribuir um array a ele. Eu acho que o que você quer, uma vez que estes são pares, é ter set1, set2, e SET3 ser um array de inteiros de tamanho 2.

E se você alterar o tipo Location a ser:

TYPE Location
  INTEGER, DIMENSION(2) :: set1, set2, set3
  INTEGER :: num_locations
END TYPE

Além disso, o loop para ler os dados não faz sentido para mim. Eu acho que eu escrevê-lo como (note que os arrays em Fortran são 1-base por padrão, não baseado em zero como em 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

Você, obviamente, precisa fazer algo para detectar e lidar com o fim da condição de arquivo também.

Se o número de locais é verdadeiramente varaible, então você precisa fazer 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

Outras dicas

Parece que você está tentando dar um inteiro o valor de dois inteiros. É algo como você tenta fazer = (ou var = 5,5).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top