如何在Fortran中找到统计模式

时间:2012-01-10 09:43:48

标签: fortran

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

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

我遇到的问题是当我尝试获取模式时。我能够计算重复值的出现次数。通过查找具有最高出现率的值,我们将能够找到模式。但我不确定如何做到这一点。 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 9 7 5 9 3 5 6

2 个答案:

答案 0 :(得分:2)

  

但是,怎么做?或者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变量中保留了最佳模式,并在FMODE变量中保留了COUNT的计数。当我们逐步浏览数组时,我们会在CURRENTCOUNT变量中计算与我们现在看到的匹配数相等的数量。

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

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

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

答案 1 :(得分:0)

它有点冗长,你可能可以摆脱可选参数,但是提供了一个例子here。他们使用快速排序算法实现here

或者,您可以使用

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

这不需要任何排序。