查看一组值是否出现在数组中的有效方法?

Efficient way to see if a set of values appear in an array?

我正在尝试检查一个一维整数数组 A 是否包含,在每个 size(A) 位置,整数集 S(也是一维数组)的任何元素,一般情况下 size(S) > 1.

简单明了的方法是执行以下嵌套循环:

DO i = 1, size(A)
   DO j = 1, size(S)
        IF(A(i) == S(j)) ** do something **
   ENDDO 
ENDDO

问题在于,对于大型数组 AS,此过程效率非常低。是否有一个内在的 FORTRAN 子例程或函数可以更快地执行此操作?或者其他方法?

我已尝试执行以下操作,但它不想编译:

DO i = 1, NNODES
   IF(A(i) == ANY(S)) ** do something **
ENDDO

出现的错误消息如下:“error #6362: The data types of the argument(s) are invalid.”我正在使用 VS2010 和 Intel Parallel Studio 2013。

表达式

A(i) == ANY(S)

lhs 上有一个整数,在 rhs 上有一个逻辑值。我们将有 none 受 C 启发的废话,将它们视为 Fortran 中的可比类型,非常感谢。实际上,它比这更糟糕,any returns 一个逻辑但在输入时需要一个逻辑数组,所以 any(array_of_int) 不会编译。

你可以试试

ANY(S==A(i))

相反。那应该给你一个可编译的解决方案。

现在,关于效率,您的第一个片段是 O(n^2)。你可以渐进地做得更好。对两个数组进行排序并串联扫描它们,即 O(n + n log n) 或类似的东西。如果您在编码方面需要帮助,请更新您的问题,尽管我怀疑它已经在 SO 上被询问和回答。

我强烈怀疑,如果你愿意,你可以检查一下,在单个(显式)循环中使用 any 也将是 O(n^2) —— 因为 any 必须在最一般的情况下运行我看不到任何现实的替代方法来扫描数组——换句话说,另一个循环。

除了 High Performance Mark 的回答之外,当您扫描排序的数组时,您可以而且应该使用二进制搜索算法。