如何计算向量中的唯一元素?



我有一个非常大的向量,我想在其中添加元素的总数,作为重复数字不代表新元素的条件,例如:

V=[0,5,1,8,9,1,1,]

我想要的答案是:5

但是我想不出一个方法来做因为使用count函数我必须知道向量的所有元素

count函数在这种情况下不起作用

哎呀,这里有一个使用树的解决方案。没有尝试去平衡它。

module treemodule
implicit none
private
public numDistinct
type Node
integer value
type(Node), pointer :: left => null(), right => null()
end type node
type, public :: Tree
private
type(Node), pointer :: root => null()
integer :: size = 0
contains
procedure insert
procedure clear
procedure print
procedure getsize
procedure, private :: insertNode
procedure, private :: deleteNode
procedure, private :: printNode
end type Tree
contains
integer function numDistinct( A )
integer, intent(in) :: A(:)
integer i
type(Tree) T
numDistinct = 3
do i = 1, size( A )
call T%insert( A(i) )
end do
numDistinct = T%getsize()
! Comment out the following if you don't need it ...
write( *, "(A)", advance="no" ) "Distinct elements: ";  call T%print;   write( *, * )
call T%clear
end function numDistinct
integer function getsize( this )
class(Tree) this
getsize = this%size
end function getsize
subroutine insert( this, value )
class(Tree) this
integer, intent(in) :: value
call this%insertNode( this%root, value )
end subroutine insert
subroutine print( this )
class(Tree) this
call this%printNode( this%root )
end subroutine print
subroutine clear( this )
class(Tree) this
call this%deleteNode( this%root )
end subroutine clear
recursive subroutine insertNode( this, ptr, value )
class(Tree) this
type(Node), pointer, intent(inout) :: ptr
integer value
if ( associated( ptr ) ) then
if ( value < ptr%value ) then
call this%insertNode( ptr%left, value )
else if ( value > ptr%value ) then
call this%insertNode( ptr%right, value )
end if
else
allocate( ptr, source=Node(value) )
this%size = this%size + 1
end if
end subroutine insertNode
recursive subroutine deleteNode( this, ptr )
class(Tree) this
type(Node), pointer, intent(inout) :: ptr
if ( associated( ptr ) ) then
call this%deleteNode( ptr%left  )
call this%deleteNode( ptr%right )
deallocate( ptr )
this%size = this%size - 1
end if
end subroutine deleteNode
recursive subroutine printNode( this, ptr )
class(Tree) this
type(Node), pointer, intent(in) :: ptr
if ( associated( ptr ) ) then
call this%printNode( ptr%left  )
write ( *, "( i0, 1x )", advance="no" ) ptr%value
call this%printNode( ptr%right )
end if
end subroutine printNode
end module treemodule
!=======================================================================
program main
use treemodule
implicit none
integer, allocatable :: A(:)
integer C
A = [ 0, 5, 1, 8, 9, 1, 1 ]
C = numDistinct( A )
write( *, "( 'Number of distinct elements = ', i0 )" ) C
end program main

可区分元素数:0 1 5 8 9
可区分元素数= 5

如果你不关心内存和性能(否则在Francescalus给出的链接中有更有效的代码):

integer function count_unique(x) result(n)
implicit none
integer, intent(in) :: x(:)
integer, allocatable :: y(:)
y = x(:)
n = 0
do while (size(y) > 0)
n = n+1
y = pack(y,mask=(y(:) /= y(1)) ! drops all elements that are 
! equals to the 1st one (included)
end do
end function count_unique

最新更新