Как найти статистический режим в Фортране - PullRequest
0 голосов
/ 10 января 2012

Я пытаюсь написать программу, чтобы найти среднее значение, медиану, режим целочисленного массива, но у меня возникли некоторые сложности при поиске режима.Ниже приведен код, который я написал до сих пор.

Сначала программа предложит пользователю ввести значение числа целых чисел, которое будет введено, а затем запрос на ввод этого числа целых чисел.Затем целые числа сортируются в порядке возрастания, а среднее и медиана находятся.

Проблема, с которой я сталкиваюсь, это когда я пытаюсь перейти в режим.Я умею считать количество повторений повторяющихся значений.Найдя значение с наибольшей частотой, мы сможем найти режим.Но я не уверен, как это сделать.Есть ли в Фортране какая-либо встроенная функция для вычисления числа вхождений входных значений и значения с наибольшим вхождением?

  PROGRAM STATISTICS
  !Created by : Rethnaraj Rambabu
  IMPLICIT NONE

  REAL, DIMENSION(:), ALLOCATABLE:: VAL
  REAL TEMP, MEDIAN
  REAL EVEN, MEAN, SUM, FMODE

  INTEGER N, I,J

  WRITE(*,*)' WHAT IS THE VALUE FOR N? '
  READ(*,*) N
  ALLOCATE(VAL(N))

  WRITE(*,*) 'ENTER THE NUMBERS'
  OPEN(1,FILE='FILE.TXT')
  READ(1,*)(VAL(I),I=1,N)
  CLOSE(1)
  WRITE(*,*) VAL

  !/---FOR SORTING----/!

  DO I=1,N-1
    DO J=1,N-1
      IF(VAL(J) > VAL(J+1)) THEN
      TEMP=VAL(J)
      VAL(J)=VAL(J+1)
      VAL(J+1)=TEMP
      END IF
    END DO
  END DO

  WRITE(*,*) VAL

  !/-----MEDIAN----/!

  IF ((N/2*2) /= N) THEN
      MEDIAN=VAL((N+1)/2)
    ELSE IF ((N/2*2) == N) THEN
      EVEN= (VAL(N/2)+VAL((N+2)/2))
      MEDIAN=EVEN/2
  END IF

  WRITE(*,*)'MEDIAN=', MEDIAN

  !/----MEAN----/
  SUM=0
  DO I=1,N
    SUM=SUM+VAL(I)
  END DO
    MEAN=SUM/N

  WRITE(*,*)'MEAN=', MEAN

  !/------MODE----/
  FMODE=1
  DO I=1,N-1
    IF (VAL(I) == VAL(I+1)) THEN
    FMODE=FMODE+1
  END IF
  END DO

  WRITE(*,*)FMODE

  END PROGRAM

FILE.TXT содержит

10 8 1 9 8 9 9 7 5 9 3 5 6

Ответы [ 2 ]

2 голосов
/ 10 января 2012

Но как это сделать? Или есть какая-нибудь встроенная функция в Фортране для вычисления количества вхождений входных значений и значения с наибольшим вхождением.

Нет, нет. Вам нужно будет рассчитать режим вручную.

Следующий код должен работать (на отсортированном массиве):

FMODE = VAL(1)
COUNT = 1
CURRENTCOUNT = 1
DO I = 2, N
    ! We are going through the loop looking for values == VAL(I-1)...
    IF (VAL(I) == VAL(I-1)) THEN
        ! We spotted another VAL(I-1), so increment the count.
        CURRENTCOUNT = CURRENTCOUNT + 1
    ELSE
        ! There are no more VAL(I-1)
        IF (CURRENTCOUNT > COUNT) THEN
            ! There were more elements of value VAL(I-1) than of value FMODE
            COUNT = CURRENTCOUNT
            FMODE = VAL(I-1)
        END IF
        ! Next we are looking for values == VAL(I), so far we have spotted one...
        CURRENTCOUNT = 1
    END
END DO
IF (CURRENTCOUNT > COUNT) THEN
    ! This means there are more elements of value VAL(N) than of value FMODE.
    FMODE = VAL(N)
END IF

Пояснение:

Мы сохранили лучший из пока что режим в переменной FMODE, а счетчик FMODE в переменной COUNT. Проходя по массиву, мы подсчитываем количество попаданий, равных тому, что мы сейчас наблюдаем, в переменной CURRENTCOUNT.

Если следующий элемент, на который мы смотрим, равен предыдущему, мы просто увеличиваем CURRENTCOUNT. Если все по-другому, тогда нам нужно сбросить CURRENTCOUNT, потому что теперь мы посчитаем количество повторений следующего элемента.

Перед тем, как сбросить CURRENTCOUNT, мы проверяем, превышает ли он предыдущий лучший результат, и, если он есть, мы перезаписываем предыдущий лучший результат (переменные FMODE и COUNT) новыми лучшими результатами (какими бы в VAL(I) и CURRENTCOUNT), прежде чем мы продолжим.

Этот сброс не происходит в конце цикла, поэтому я вставил еще одну проверку в конце, если наиболее частый элемент оказывается последним элементом цикла. В этом случае мы перезаписываем FMODE, как в цикле.

0 голосов
/ 10 января 2012

Это немного длинно, вы, вероятно, могли бы избавиться от необязательного аргумента, но здесь приведен пример здесь . Они используют алгоритм быстрой сортировки, реализованный здесь .

В качестве альтернативы, вы можете использовать

integer function mode(arr) result(m)
  implicit none

  integer, dimension(:), intent(in) :: arr

  ! Local variables
  integer, dimension(:), allocatable :: counts
  integer :: i, astat
  character(len=128) :: error_str

  ! Initialise array to count occurrences of each value.
  allocate(counts(minval(arr):maxval(arr)), stat=astat, errmsg=error_str)
    if (astat/=0) then
      print'("Allocation of counts array failed.")'
      print*, error_str
    end if

  counts = 0

  ! Loop over inputted array, counting occurrence of each value.
  do i=1,size(arr)
      counts(arr(i)) = counts(arr(i)) + 1
  end do

  ! Finally, find the mode
  m = minloc(abs(counts - maxval(counts)),1)

end function mode

Сортировка не требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...