在Fortran中查找两个数组的交集

时间:2015-05-14 21:45:50

标签: arrays fortran fortran90 fortran95 set-intersection

我正在尝试在Fortran中生成两个1-D数组的交叉。

目的是将此交集用作maxloc中的掩码,以便我可以将最多的几个元素从一个数组拉到另一个数组中(类似于在最大堆中重复删除根的行为)。

目前我只是将maxloc找到的索引的值设置为零,然后我将该索引处的值插入第二个数组,但我希望Fortran有一个聪明的与掩码相关的方法。 (在最大检索过程中保留原始数组也很好)

1 个答案:

答案 0 :(得分:6)

我不太清楚你的意思。如果要按索引比较两个数组索引,只需使用==即可,如下所示:

INTEGER :: a(4), b(4)
LOGICAL :: inter(4)

a = (/ 1, 2, 3, 4 /)
b = (/ 4, 2, 3, 1 /)
inter = (a == b)  ! (/ F, T, T, F /)

这在技术上不是一个交集,但MASK中的MAXLOC需要是LOGICAL的数组,所以我认为这就是你想要的。

如果你想测试a的值是否在b的任何位置,你必须使用至少一个DO循环,我想:

DO j = 1, size(a)
    inter(j) = any(a(j) == b)
END DO

如果你想找到最大的,比方说,n值,你可以使用这样的东西:

function largest(vars, n)
    implicit none
    integer, intent(in) :: n
    real, dimension(:), intent(in) :: vars
    real, dimension(n) :: largest
    integer :: i
    logical, dimension(size(vars)) :: m
    integer :: mloc

    m = .TRUE.

    do i = 1, n
       mloc = maxloc(vars, DIM=1, MASK=m)
       m(mloc) = .FALSE.
       largest(i) = vars(mloc)
    end do
    return
end function largest

基本上它使用一个全部为真的掩码,然后每次将掩码恢复为最高为false,以便在下一次迭代中不再获取该值。

当然,这是有序的(n * size(var)),所以如果n很大,那么进行冒泡排序可能会更快,直到最后累积了n个最大值,然后选择它们起来。