fortran 在数组中找到一系列整数
fortran find series of integers in array
Fortran 中是否有函数或方法来查找数组中的一系列整数和 return 数组中的位置或如果匹配则计数?
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 34, 33, 19, 25, 36)
找到 (8,56,33)
return3 作为位置或 1 作为匹配项
如果是多个:
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36)
找到 (8,56,33)
Return 3 和 10 或 2
fortran 中是否有处理这种数组搜索的函数?
简短的回答是 "No",Fortran 中没有这样的 intrinsic 函数。
通常期望您自己编写这样的内容。例如:
- 从所有可能的起始索引数组开始
- 确定保留索引的条件
- 依次只保留满足条件的索引
内在过程pack
在这里非常有用,它可用于仅保留数组(您的起始位置)中符合特定条件(您保留起始位置的条件)的值。
下面的(未经过广泛测试!)程序 "test.f90" 说明了用法:
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
对于你问题中的两个测试用例,编译和运行给出以下输出:
$ 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
和
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
您所追求的是一种叫做滑动window 搜索算法的东西。一个简单的实现如下:
program test
implicit none
integer, dimension(:), allocatable :: arr
integer, dimension(:), allocatable :: seq
integer :: i
arr = [1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36]
seq = [8, 56, 33]
do i=1,size(arr)-size(seq)+1
if (all(arr(i:i+size(seq)-1) == seq)) print *, i
end do
end program
这不是最优化的版本,但在大多数情况下都能胜任。
Fortran 中是否有函数或方法来查找数组中的一系列整数和 return 数组中的位置或如果匹配则计数?
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 34, 33, 19, 25, 36)
找到 (8,56,33)
return3 作为位置或 1 作为匹配项
如果是多个:
(1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36)
找到 (8,56,33)
Return 3 和 10 或 2
fortran 中是否有处理这种数组搜索的函数?
简短的回答是 "No",Fortran 中没有这样的 intrinsic 函数。
通常期望您自己编写这样的内容。例如:
- 从所有可能的起始索引数组开始
- 确定保留索引的条件
- 依次只保留满足条件的索引
内在过程pack
在这里非常有用,它可用于仅保留数组(您的起始位置)中符合特定条件(您保留起始位置的条件)的值。
下面的(未经过广泛测试!)程序 "test.f90" 说明了用法:
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
对于你问题中的两个测试用例,编译和运行给出以下输出:
$ 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
和
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
您所追求的是一种叫做滑动window 搜索算法的东西。一个简单的实现如下:
program test
implicit none
integer, dimension(:), allocatable :: arr
integer, dimension(:), allocatable :: seq
integer :: i
arr = [1, 5, 8, 56, 33, 56, 78, 123, 78, 8, 56, 33, 19, 25, 36]
seq = [8, 56, 33]
do i=1,size(arr)-size(seq)+1
if (all(arr(i:i+size(seq)-1) == seq)) print *, i
end do
end program
这不是最优化的版本,但在大多数情况下都能胜任。