2015-07-28 2 views
0

У меня есть два массива fListU и fListD, оба из которых содержат 4-х кортежей. В частности:Массирование массивов в Fortran

fListU = [(2, 1, 1, 0), (2, 5, 5, 0), (5, 4, 10, 0), (6, 1, 5, 0), (6, 5, 7, 0)] 
fListD = [(1, 4, 0, 4), (3, 4, 0, 4), (5, 4, 0, 6)] 

Теперь я хочу, чтобы соединить их в один массив, с условием, что, когда первые два элемента кортежей равны, то следует добавить третий и четвертый элементы двух списков. В этом случае результат Ищу является

fList = [(2, 1, 1, 0), (2, 5, 5, 0), (5, 4, 10, 6), (6, 1, 5, 0), 
     (6, 5, 7, 0), (1, 4, 0, 4), (3, 4, 0, 4)] 

где (5, 4, 10, 0) и (5, 4, 0, 6) объединяются (5, 4, 10, 6) ,

Это то, что я пробовал.

ALLOCATE (fList((n-1)**2,4)) 
fList = 0 
p = 1 ! p signifies the position in fList. 
DO k = 1, ((n-1)**2), 1 ! k is the index for fListD 
    DO l = 1, ((n-1)**2), 1 ! l is the index for fListU 
    IF (ALL (fListU(l,1:2) == fListD(k,1:2))) THEN 
     fList(p,1:2) = fListU(l,1:2) 
     fList(p,3) = fListU(l,3) 
     fList(p,4) = fListD(k,4) 
    ELSE 
     fList(p,:) = fListU(l,:) 
     p = p+1 
     fList(p,:) = fListD(k,:) 
     p = p+1 
    END IF 
    END DO 
END DO 

Это не то, что я хочу. В чем проблема?

+0

Вы хотите * добавить * третье и четвертое значения, заменить их? –

+1

Подождите, 'Fortran' поддерживает кортежи? – ja72

+0

@ ja72 Я предполагаю, что он имел в виду, что 4 числа контекстуально принадлежат друг другу. Я никогда не слышал о поддержке Fortran кортежей, таких как python. Вы увидите, что в моем ответе я использовал термин * кортежи *, но он рассматривается как одно из двух измерений массива. – chw21

ответ

1

Я не уверен, что вы читаете в fListU и fListD. Единственное, что вам нужно понять, это то, что в Fortran (кроме большинства других языков программирования) первый индекс многомерного массива - это наиболее быстро меняющийся. Вот почему так, как вы читаете данные, так важно: если вы читаете данные последовательно или используете reshape, то второй элемент, который вы читаете, будет находиться в позиции (2, 1), а не (1, 2), как и следовало ожидать.

Поэтому я настоятельно рекомендую, чтобы иметь форму, как fListU(4, 5), не (5, 4), и, следовательно, рассмотреть первые два элемент кортежа, как flist(1:2, p).

Это возможное решение, которое знает длины двух входных массивов. Выход будет по-прежнему содержать другую строку всех нулей, потому что я не запрограммировал его, чтобы получить размер выходного массива вправо (вместо этого он просто использует сумму размеров входных массивов).

program Combine_List_Simple 
    implicit none 
    integer, dimension(:, :), allocatable :: fListU, fListD, fList 
    integer :: u_size, d_size 
    integer :: u_index, d_index, f_index 

    u_size = 5 
    allocate(fListU(4, u_size)) 
    fListU = reshape((/2, 1, 1, 0, 2, 5, 5, 0, 5, 4, 10, 0, & 
         6, 1, 5, 0, 6, 5, 7, 0/), (/4, u_size/)) 

    d_size = 3 
    allocate(fListD(4, d_size)) 
    fListD = reshape((/1, 4, 0, 4, 3, 4, 0, 4, 5, 4, 0, 6/), & 
        (/4, d_size/)) 

    allocate(fList(4, u_size + d_size)) 
    flist(:, 1:u_size) = fListU(:, :) 
    flist(:, u_size+1:) = 0 
    f_index = u_size+1 
    d_loop : do d_index = 1, d_size 
     do u_index = 1, u_size 
     if (all(fListD(1:2, d_index) == fList(1:2, u_index))) then 
      fList(4, u_index) = fListD(4, d_index) 
      cycle d_loop 
     end if 
     end do 
     fList(:, f_index) = fListD(:, d_index) 
     f_index = f_index+1 
    end do d_loop 

    write(*, '(4I4)') fList 

end program Combine_List_Simple 

Этот код также предполагает, что четвёртый элемент всех кортежей в fListU и третий элемент всех кортежей в fListD равен нуль. Но, похоже, ваш код тоже предполагает это. Также предполагается, что комбинация 1-го и 2-го элементов кортежей уникальна в каждом из входных массивов.

Во-первых, я полностью копирую содержимое fListU в fList. Затем я перехожу через fListD и сравниваю его с первым записями в fList, потому что здесь находится содержимое fListU. Если он находит совпадение, он обновляет только четвертый элемент кортежа, а затем циклирует цикл массива fListD.

Только если он не найдет соответствия, он достигнет конца внутреннего контура, а затем добавит кортеж к fList.

+0

Большое спасибо, chw21! – user27430

Смежные вопросы