我正在尝试编写一个程序来查找整数数组的均值,中位数模式,但在查找模式时遇到了一些复杂问题。以下是我到目前为止编写的代码。
首先,程序将提示用户输入将输入的整数数值,然后输入请求输入该整数数。然后按升序对整数进行排序,找到平均值和中位数。
我遇到的问题是当我尝试获取模式时。我能够计算重复值的出现次数。通过查找具有最高出现率的值,我们将能够找到模式。但我不确定如何做到这一点。 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
答案 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
之前,我们会检查它是否大于之前的最佳结果,如果是,我们会覆盖之前的最佳结果(FMODE
和COUNT
变量)在我们继续之前,新的最佳结果(无论是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
这不需要任何排序。