Как найти максимальное и минимальное значение из текстового файла в Фортране
PROGRAM maxmin
IMPLICIT NONE
INTEGER :: openStatus, ioStatus
INTEGER :: counter, counter2, counter3
INTEGER :: numberOfInts
INTEGER :: int_val, max_int, min_int
OPEN (UNIT=12, FILE="INT.DAT", STATUS="OLD", ACTION="READWRITE", IOSTAT=openStatus)
IF (openStatus > 0) THEN
WRITE (*, '(1X, A)') "Can't open file"
STOP
END IF
WRITE (*, '(1X, A)') "How many integers do you want to read?"
READ (*, '(I6)') numberOfInts
DO counter = 1, numberOfInts
READ (12, '(1X, I5)', IOSTAT = ioStatus) int_val
IF (ioStatus < 0) THEN
WRITE (*, '(1X, A)') "End of file"
EXIT
END IF
END DO
DO counter2 = 1, numberOfInts, 1
If (counter2 == 1) Then
max_int = int_val
END IF
If (int_val > max_int) Then
max_int = int_val
END IF
END DO
DO counter3 = 1, numberOfInts, 1
If (counter3 == 1) Then
min_int = int_val
END IF
If (int_val < min_int) Then
min_int = int_val
END IF
END DO
WRITE (*, '(1X, A)', ADVANCE = "NO") "The max is:"
WRITE (*, '(1X, I4)') max_int
WRITE (*, '(1X, A)', ADVANCE = "NO") "The min is:"
WRITE (*, '(11X, I4)') min_int
CLOSE (12)
END PROGRAM maxmin
Из изображения выше, когда я печатаю значения max и min, они всегда печатают последнее число в этом текстовом файле, а это 7. Я не понимаю, как решить проблему.
Я знаю, что весь код верен, но эта минимальная часть кода определенно не так. Я так растерялся.
2 ответа
Что это
DO counter = 1, numberOfInts
READ (12, '(1X, I5)', IOSTAT = ioStatus) int_val
IF (ioStatus < 0) THEN
WRITE (*, '(1X, A)') "End of file"
EXIT
END IF
END DO
делает то, что он многократно читает одно число, затем читает другое число и перезаписывает предыдущее значение и так далее. В конце int_val
содержит последнее прочитанное значение, потому что все предыдущие значения были перезаписаны последними.
Поэтому, когда вы приходите сюда
DO counter2 = 1, numberOfInts, 1
If (counter2 == 1) Then
max_int = int_val
END IF
If (int_val > max_int) Then
max_int = int_val
END IF
END DO
int_val
это только последний номер, который был прочитан, и это будет минимум и максимум.
Вы должны либо сохранить значения в массиве, либо сделать все в одном цикле:
max_int = -(huge(max_int)-1) !make initial max_int very small
min_int = huge(max_int) !make initial min_int very big
DO counter = 1, numberOfInts
READ (12, '(1X, I5)', IOSTAT = ioStatus) int_val
IF (ioStatus < 0) THEN
WRITE (*, '(1X, A)') "End of file"
EXIT
END IF
If (int_val > max_int) Then
max_int = int_val
END IF
If (int_val < min_int) Then
min_int = int_val
END IF
END DO
Другой способ - использовать встроенные функции (MAXVAL, MAXLOC, MINVAL, MINLOC), а также поместить все значения в массив или вектор.
PROGRAM maxmin
IMPLICIT NONE
INTEGER :: openStatus, ioStatus
INTEGER :: counter!, counter2, counter3
INTEGER, PARAMETER :: MaxIn = 1000000
INTEGER, DIMENSION(MaxIn) :: int_val
INTEGER :: numberOfInts
INTEGER :: max_int, min_int
OPEN (UNIT=12, FILE="INT.DAT", STATUS="OLD", ACTION="READWRITE", IOSTAT=openStatus)
IF (openStatus > 0) THEN
WRITE (*, '(1X, A)') "Can't open file"
STOP
END IF
WRITE (*, '(1X, A)') "How many integers do you want to read?"
READ (*, '(I6)') numberOfInts
!Test array size....
IF(numberOfInts > MaxIn) THEN
WRITE (*, '(1X,A,I9,A,I7)') "Requested " , numberOfInts," However Array size=",MaxIn
STOP
ENDIF
DO counter = 1, numberOfInts
READ (12, '(1X, I5)', IOSTAT = ioStatus) int_val(Counter)
IF (ioStatus < 0) THEN
WRITE (*, '(1X, A)') "End of file"
EXIT
END IF
END DO
min_int = MINVAL(int_val(1:numberOfInts))
max_int = MAXVAL(int_val(1:numberOfInts))
WRITE (*, '(1X, A)', ADVANCE = "NO") "The max is:"
WRITE (*, '(1X, I4)') max_int
WRITE (*, '(1X, A)', ADVANCE = "NO") "The min is:"
WRITE (*, '(11X, I4)') min_int
CLOSE (12)
END PROGRAM maxmin