I'm trying to write a program to find the mean, median, mode of an integer array but am having some complications in finding the mode. The following is the code that I've written so far.
我试着写一个程序来找出一个整数数组的均值,中位数,模式,但在找到模式时遇到了一些麻烦。下面是我写的代码。
First, the program will prompt user to enter a value for the number of integers that will be entered followed by request to enter that number of integers. The integers are then sorted in ascending order and the mean and median are found.
首先,该程序将提示用户输入将输入的整数的数量,然后请求输入这些整数的数量。然后按升序排列整数,并找到平均值和中位数。
The problem I am having is when I try to get the mode. I am able to count the number of occurrence of a repetitive value. By finding the value with highest occurrence, we'll be able to find Mode. But I am unsure how to do this. Is there any intrinsic function in Fortran to calculate number of occurrence of input values and the value with highest occurrence?
我遇到的问题是当我试着获得模式的时候。我能够计算出重复值的出现次数。通过找到具有最高发生率的值,我们将能够找到模式。但我不知道该怎么做。在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
The FILE.TXT
contains
该文件。TXT包含
10 8 1 9 8 9 9 7 5 9 3 5 6
10 8 1 9 9 9 9 7 5 9 3 5 6。
2 个解决方案
#1
2
But, how to do that? Or is there any intrinsic function in Fortran to calculate number of occurrence of input values and the value with highest occurrence.
但是,怎么做呢?或者在Fortran中有任何内在的函数来计算输入值的发生次数和最高发生的值。
No, there is not. You'll have to calculate the mode by hand.
不,没有。你必须手工计算模式。
The following code should work (on a sorted array):
下面的代码应该工作(在已排序的数组中):
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
Explanation:
解释:
We keep the best-so-far mode in the FMODE
variable, and the count of the FMODE
in the COUNT
variable. As we step through the array we count the number of hits that are equal to what we are looking at now, in the CURRENTCOUNT
variable.
我们在FMODE变量中保留了最好的模式,并在count变量中计算FMODE的计数。当我们通过数组时,我们计算的命中次数等于我们现在看到的,在CURRENTCOUNT变量中。
If the next item we look at is equal to the previous, we simply increment the CURRENTCOUNT
. If it's different, then we need to reset the CURRENTCOUNT
, because we will now count the number of duplications of the next element.
如果我们看到的下一个项等于前面的项,我们只需增加CURRENTCOUNT。如果是不同的,那么我们需要重置CURRENTCOUNT,因为我们现在将计算下一个元素的重复数。
Before we reset the CURRENTCOUNT
we check if it's bigger than the previous best result, and if it is, we overwrite the previous best result (the FMODE
and COUNT
variables) with the new best results (whatever is at VAL(I)
and CURRENTCOUNT
), before we continue.
在我们重置CURRENTCOUNT之前,我们检查它是否大于之前的最佳结果,如果是,我们在继续之前,重写了之前最好的结果(FMODE和COUNT变量)和新的最佳结果(无论在VAL(I)和CURRENTCOUNT中是什么)。
This reset doesn't happen at the end of the loop, so I inserted another check at the end in case the most frequent element happens to be the final element of the loop. In that case we overwrite FMODE
, like we would have done in the loop.
这个复位不会在循环结束时发生,所以我在最后插入了另一个检查,以防最频繁的元素恰好是循环的最后一个元素。在这种情况下,我们重写FMODE,就像我们在循环中做的那样。
#2
0
It is a bit lengthy, you could probably get rid of the optional argument, but there is an example provided here. They use the quick sort algorithm as implemented here.
它有点冗长,您可能会删除可选参数,但这里提供了一个示例。他们使用这里实现的快速排序算法。
Alternatively, you could use
或者,您可以使用
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
This doesn't require any sorting.
这不需要任何排序。
#1
2
But, how to do that? Or is there any intrinsic function in Fortran to calculate number of occurrence of input values and the value with highest occurrence.
但是,怎么做呢?或者在Fortran中有任何内在的函数来计算输入值的发生次数和最高发生的值。
No, there is not. You'll have to calculate the mode by hand.
不,没有。你必须手工计算模式。
The following code should work (on a sorted array):
下面的代码应该工作(在已排序的数组中):
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
Explanation:
解释:
We keep the best-so-far mode in the FMODE
variable, and the count of the FMODE
in the COUNT
variable. As we step through the array we count the number of hits that are equal to what we are looking at now, in the CURRENTCOUNT
variable.
我们在FMODE变量中保留了最好的模式,并在count变量中计算FMODE的计数。当我们通过数组时,我们计算的命中次数等于我们现在看到的,在CURRENTCOUNT变量中。
If the next item we look at is equal to the previous, we simply increment the CURRENTCOUNT
. If it's different, then we need to reset the CURRENTCOUNT
, because we will now count the number of duplications of the next element.
如果我们看到的下一个项等于前面的项,我们只需增加CURRENTCOUNT。如果是不同的,那么我们需要重置CURRENTCOUNT,因为我们现在将计算下一个元素的重复数。
Before we reset the CURRENTCOUNT
we check if it's bigger than the previous best result, and if it is, we overwrite the previous best result (the FMODE
and COUNT
variables) with the new best results (whatever is at VAL(I)
and CURRENTCOUNT
), before we continue.
在我们重置CURRENTCOUNT之前,我们检查它是否大于之前的最佳结果,如果是,我们在继续之前,重写了之前最好的结果(FMODE和COUNT变量)和新的最佳结果(无论在VAL(I)和CURRENTCOUNT中是什么)。
This reset doesn't happen at the end of the loop, so I inserted another check at the end in case the most frequent element happens to be the final element of the loop. In that case we overwrite FMODE
, like we would have done in the loop.
这个复位不会在循环结束时发生,所以我在最后插入了另一个检查,以防最频繁的元素恰好是循环的最后一个元素。在这种情况下,我们重写FMODE,就像我们在循环中做的那样。
#2
0
It is a bit lengthy, you could probably get rid of the optional argument, but there is an example provided here. They use the quick sort algorithm as implemented here.
它有点冗长,您可能会删除可选参数,但这里提供了一个示例。他们使用这里实现的快速排序算法。
Alternatively, you could use
或者,您可以使用
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
This doesn't require any sorting.
这不需要任何排序。