Is there a function or method in Fortran to find as series of integers in an array and return a location in the array or count if matches?
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 34, 33, 19, 25, 36)
find (8,56,33)
either return 3 as location or 1 as a match
If multiple:
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36)
find (8,56,33)
Return 3 and 10 or 2
Are there functions in fortran to handle this kind of array searching?
The short answer is "No", there is no such intrinsic function in Fortran.
You are typically be expected to write something like this yourself. For example:
The intrinsic procedure pack
is quite useful here, it can be used to only retain values from an array (your starting locations) that match a certain condition (your condition for keeping starting locations).
The (not extensively tested!) program "test.f90" below illustrates the use:
module mod_finder
implicit none
contains
subroutine find_start_locs(array, sub_array, start_locs)
integer, intent(in) :: array(:)
integer, intent(in) :: sub_array(:)
integer, allocatable, intent(out) :: start_locs(:)
integer :: i
! initialize result with all possible starting indices
start_locs = [(i, i = 1, size(array)-size(sub_array)+1)]
! sequentially keep only those indices that satisfy a condition
do i = 1, size(sub_array)
! condition for keeping: the value of array(start_locs + i - 1) must be equal to the value of sub_array(i)
! use PACK to only keep start_locs that satisfy this condition
start_locs = PACK(start_locs, array(start_locs + i - 1) == sub_array(i))
if (size(start_locs) == 0) then
exit
end if
end do
end subroutine find_start_locs
end module mod_finder
program test
use mod_finder
implicit none
integer, allocatable :: arr(:)
integer, allocatable :: seq(:)
integer, allocatable :: res(:)
! arr = [1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 34, 33, 19, 25, 36]
arr = [1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36]
seq = [8, 56, 33]
call find_start_locs(arr, seq, res)
print *, "array: ", arr
print *, "sequence: ", seq
print *, "locations: ", res
print *, "# matches: ", size(res)
end program test
For the two test cases in your question, compiling and running gives the following output:
$ gfortran -O2 -g -Wall -Wextra -fcheck=all test.f90
$ ./a.out
array: 1 5 8 56 33 56 78 123 78 8 34 33 19 25 36
sequence: 8 56 33
locations: 3
# matches: 1
and
array: 1 5 8 56 33 56 78 123 78 8 56 33 19 25 36
sequence: 8 56 33
locations: 3 10
# matches: 2