Найти индексы последовательного значения флага в одномерном массиве
Я ищу, чтобы найти значение 0 в одномерном массиве. У меня есть несколько значений 0 в этом массиве, большую часть времени подряд 0 значений. Теперь, что я точно хочу сделать, это найти индексы вхождения первого нулевого значения и вхождения последнего нулевого значения в каждом последовательном вхождении, ниже я приведу пример, чтобы прояснить ситуацию: представьте, что у меня есть следующий массив:
A= 0.0 0.0 0.0 0.0 0.0 0.0 0.38458693526004206 0.37630968444637147 0.40920888023862656 0.37240138383511134 0.38032672100490084 0.37013107455599198 0.40263333907360693 0.36804456033540955 0.41199172743738527 0.42761170349633443 0.39300715826673704 0.39783513932402137 0.44013743441396674 0.435127008833611 0.48217350280280391 0.47501246018014148 0.49234819258730078 0.54559998531569354 0.47840534103437832 0.0 0.0 0.0 0.51927791704510429 0.0 0.0 0.0 0.0 0.0 0.45862555500619961 0.50158980306905965 0.45676444815553296 0.49679306608627022 0.53878698007533210 0.50186256107128602 0.51714780706878094 0.53005606067091249 0.48409168179213419 0.48594430950932133 0.50963106475909081 0.49300327248076087 0.50531667704394834 0.46415085995913757 0.51930900041928330
поэтому я ищу первое местоположение и последнее местоположение нуля в каждом последующем вхождении, я должен получить следующее:
min_loc_1=1
max_loc_1=6
min_loc_2=26
max_loc_2=28
min_loc_3=30
max_loc_3=34
Теперь я попробовал комбинацию any
, minloc
, maxloc
, или же forall
, но я не могу понять это
do ijk = 1, size(work1)
if (work1(ijk) .eq. 0) then
location1(ijk) = ijk
end if
end do
min_loc=minloc(location1)
max_loc1=maxloc(location1)
Я не могу использовать where
потому что я вызываю подпрограмму внутри нее, и Фортрану это не нравится, по-видимому.
1 ответ
Ограниченное количество испытаний убедило меня, что это решает вашу непосредственную проблему. Я не проверял это подробно, я оставлю это вам. Он записывает индексы запуска и остановки каждого запуска 0
с в массив b
:
INTEGER, DIMENSION(:),ALLOCATABLE :: b
LOGICAL :: zz
...
ALLOCATE(b(0))
zz = .false.
DO ix = 1, SIZE(a)
IF (.NOT.zz.AND.a(ix)==0) THEN
b = [b,ix]
zz = .TRUE.
END IF
IF (zz.AND.a(ix)/=0) THEN
b = [b,ix-1]
zz = .FALSE.
END IF
END DO
Это приводит к тому, что при загрузке массива вы показываете
b == [1 6 26 28 30 34]
Если это не нравится, это также работает:
b = [(ix,ix=1,SIZE(a))]
WHERE(a/=0.0) b = 0
c = PACK(b,b/=0)
b = PACK(c,(CSHIFT(c,1)-c)*(CSHIFT(c,-1)-c)/=-1)
Если вы не можете понять эту версию, придерживайтесь явного зацикливания в первом фрагменте.