如何在Fortran中找到统计模式



我正试图编写一个程序来查找整数数组的平均值、中值和模式,但在查找模式时遇到了一些复杂问题。以下是我迄今为止编写的代码。

首先,程序将提示用户输入将要输入的整数数的值,然后请求输入该整数数。然后按升序对整数进行排序,得到平均值和中值。

我遇到的问题是当我试图获得模式时。我能够计算重复值的出现次数。通过找到出现次数最多的值,我们将能够找到Mode。但我不确定该怎么做。Fortran中是否有任何内在函数来计算输入值的出现次数以及出现次数最多的值

  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 7 5 9 3 5 6

但是,如何做到这一点?或者Fortran中是否有任何内在函数来计算输入值的出现次数和出现次数最多的值。

不,没有。你必须手工计算模式。

以下代码应该可以工作(在排序数组上):

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变量中保持迄今为止的最佳模式,在COUNT变量中保持FMODE的计数。当我们逐步遍历数组时,我们在CURRENTCOUNT变量中计算与我们现在看到的内容相等的命中数。

如果我们看到的下一项与上一项相等,我们只需增加CURRENTCOUNT。如果不同,那么我们需要重置CURRENTCOUNT,因为我们现在将计算下一个元素的重复次数。

在重置CURRENTCOUNT之前,我们检查它是否大于以前的最佳结果,如果是,我们用新的最佳结果(无论在VAL(I)CURRENTCOUNT处是什么)覆盖以前的最佳效果(FMODECOUNT变量),然后继续。

这种重置不会发生在循环的末尾,所以我在末尾插入了另一个检查,以防最频繁的元素恰好是循环的最后一个元素。在这种情况下,我们会覆盖FMODE,就像我们在循环中所做的那样。

这有点长,您可能会去掉可选参数,但这里提供了一个示例。他们使用这里实现的快速排序算法。

或者,您可以使用

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

这不需要任何排序。

最新更新