Найти индексы последовательного значения флага в одномерном массиве

Я ищу, чтобы найти значение 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)

Если вы не можете понять эту версию, придерживайтесь явного зацикливания в первом фрагменте.

Другие вопросы по тегам