在Fortran中删除二维数组中的重复元素 [英] Remove repeated elements in a 2D array in Fortran

查看:1743
本文介绍了在Fortran中删除二维数组中的重复元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


是否可能有一个从数组中删除所有2D重复节点的函数? A(xy,1)= 1,2,4,5,5,5,5,5, A(xy,2)= / 5,2,5, 6 ,7,6,6,3,7,6 ,6 /

之后


A(xy,1)= / 1,2,4,5,5,5,9 ,6,8,2,4 /

A(xy,2)= / 5,2,5,6 / 7,6,6 ,6,3,7,6 /






当我尝试执行@ HighPerformanceMark's代码在一个空白的程序中,有几个编译错误,我没有得到:

  repeating.f90:24.20:

mask(ix)= NOT(ANY(arraya(1,:ix-1)== arraya(1,ix).AND。&
1
错误:'i' (1)处的不内在参数必须是INTEGER
repeating.f90:29.11:

ALLOCATE(index_vector,source = PACK([(ix,ix = 1,numcols)],mask))
1
错误:ALLOCATE语句在(1)
repeating.f90:32.11:
...

您可以说些什么这是什么?

解决方案

是的,这是做你想做的一种方法。请注意,这会将数组A的唯一元素复制到一个名为B的新数组中,而不是实时调整A的大小。我调用了数组 arraya arrayb ,因为1个字符的名称违背了我的编码标准。

  PROGRAM测试

USE iso_fortran_env

隐式无

INTEGER,PARAMETER :: numrows = 2
INTEGER,PARAMETER :: numcols = 11

INTEGER,DIMENSION(numrows,numcols):: arraya
LOGICAL,DIMENSION(:), ALLOCATABLE :: mask
INTEGER,DIMENSION(:, :),ALLOCATABLE :: arrayb
INTEGER :: ix
INTEGER,DIMENSION(:),ALLOCATABLE :: index_vector

arraya(1,:) = [1,2,4,5,5,9,6,8,2,5,4]
arraya(2,:) = [5,2,5, 6,7,6,6,3,7,6,6]

!首先,找到重复元素
ALLOCATE(mask(numcols))
mask = .TRUE。

DO ix = numcols,2,-1
mask(ix)= .NOT。(ANY(arraya(1,:ix-1)== arraya(1,ix))。 AND&
arraya(2,:ix-1)== arraya(2,ix)))
END DO

!创建索引向量
ALLOCATE(index_vector,source = PACK([(ix,ix = 1,numcols)],mask))

!现在将a的唯一元素复制到b
ALLOCATE(arrayb,source = arraya(:,index_vector))

END PROGRAM test

另请注意:


  • 我把它写成一个程序,你可能想把它重写成一个函数,该函数返回我所谓的 arrayb

  • 没有错误检查或任何你可以省掉 index_vector ,并重写最后一条语句,如
  • code> ALLOCATE(arrayb,source = arraya(:,PACK([(ix,ix = 1,numcols)],mask)))但是(a) (b)我没有对它进行测试。
  • 我只在您的输入数据和一些细微变化上测试过。

  • 第一个(最左边的)重复元素的实例。


I would like to know whether it is possible to have a function that erases all of the 2D repeated nodes from an array, i.e.:

A(xy,1:2)

A(xy,1) = /1,2,4,5,5,9,6,8,2,5,4/

A(xy,2) = /5,2,5,6,7,6,6,3,7,6,6/

After

A(xy,1) = /1,2,4,5,5,9,6,8,2,4/

A(xy,2) = /5,2,5,6,7,6,6,3,7,6/


When I try to execute @HighPerformanceMark's code in a blank program, there are several compiling errors that I do not get:

  repeating.f90:24.20:

       mask(ix) = NOT(ANY(arraya(1,:ix-1)==arraya(1,ix).AND.&
                      1
  Error: 'i' argument of 'not' intrinsic at (1) must be INTEGER
  repeating.f90:29.11:

    ALLOCATE(index_vector, source=PACK([(ix, ix=1,numcols) ],mask))
             1
  Error: Array specification required in ALLOCATE statement at (1)
  repeating.f90:32.11:
...

What can you say about this?

解决方案

Yes, here's one way of doing what you want. Note that this will copy the unique elements of array A into a new array called B rather than resize A on the fly. I've called the arrays arraya and arrayb because 1-character names go against my coding standards.

PROGRAM test

  USE iso_fortran_env

  IMPLICIT NONE

  INTEGER, PARAMETER :: numrows = 2
  INTEGER, PARAMETER :: numcols = 11

  INTEGER, DIMENSION(numrows,numcols) :: arraya
  LOGICAL, DIMENSION(:), ALLOCATABLE :: mask
  INTEGER, DIMENSION(:,:), ALLOCATABLE :: arrayb
  INTEGER :: ix
  INTEGER, DIMENSION(:), ALLOCATABLE :: index_vector

  arraya(1,:) = [1,2,4,5,5,9,6,8,2,5,4]
  arraya(2,:) = [5,2,5,6,7,6,6,3,7,6,6]

  ! First, find the duplicate elements
  ALLOCATE(mask(numcols))
  mask = .TRUE.

  DO ix = numcols,2,-1
     mask(ix) = .NOT.(ANY(arraya(1,:ix-1)==arraya(1,ix).AND.&
                    arraya(2,:ix-1)==arraya(2,ix)))
  END DO

  ! Make an index vector
  ALLOCATE(index_vector, source=PACK([(ix, ix=1,numcols) ],mask))

  ! Now copy the unique elements of a into b
  ALLOCATE(arrayb, source=arraya(:,index_vector))

END PROGRAM test

Note also:

  • I've written this as a program, you might want to rewrite it into a function which returns what I've called arrayb.
  • There's no error checking or any of that sort of stuff, this is not production-ready code.
  • You could probably dispense with index_vector and rewrite the last statement like this ALLOCATE(arrayb, source=arraya(:,PACK([(ix, ix=1,numcols) ],mask))) but (a) that's a wee bit cryptic and (b) I haven't tested it.
  • I've only tested this on your input data and a few minor variations.
  • This keeps the first (leftmost) instance of duplicated elements.

这篇关于在Fortran中删除二维数组中的重复元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆