2014-09-10 1 views
0

Первый раз, когда у меня был (возможно, очень простой) вопрос.Назначение элементов массива на основе элементов в другом массиве

Я хотел присвоить значениям элементов в одном массиве (А) на основе соответствующих значений в другом массиве (B), например, если A (1) = 2 присваивает 4 B (1).

Я предполагал, что это будет достигнуто с использованием циклов DO и некоторых операторов if. Однако те строки, которые я использую, похоже, ссылаются на индекс цикла, а не на конкретный элемент в этой точке.

Может ли кто-нибудь указать мне правильное направление?

+2

Это не ясно, что вы пытаетесь сделать. Можете ли вы предоставить какой-то код и пример того, что он должен делать? –

+0

Нет ничего плохого с петлями. Я всегда удивляюсь, что люди изобретают очень умные выражения массивов, просто чтобы избежать циклов, которые, вероятно, более эффективны. –

ответ

1

Возможно, вы используете назначение маскированных массивов . Учитывая два массива, A и B, той же формы (то же самое количество рангов, одинакового размера в каждом измерении), и если вы хотите установить элементы B на 4, где соответствующий элемент A равен 2, вы можете просто написать

where(A==2) B = 4 

where объединяется с elsewhere, а как if и else if, и есть end where тоже. Для получения дополнительной информации обратитесь к своей любимой документации.

Если вы не можете выразить свою операцию с помощью where, вы можете (если у вас есть современный компилятор) заинтересовать конструкцию do concurrent. И, если все остальное терпит неудачу, есть хорошие старомодные do и if, чтобы снова упасть.

+0

Я должен добавить, в знак признания того, что Франсуа Жак делает выше, что слишком много современного времени программирования Фортрана действительно потрачено на разработку очень умных выражений массива, сравнивая их с эквивалентным кодом на основе цикла (который занял бы около 1/10 время на разработку), а затем изучение того, что петлевой подход выполняется быстрее. 'where' является опрятным, но не удивляйтесь, если' do' попадает на приз. –

2

Вы также можете попробовать конструкцию с merge ... merge формирует новый массив из двух существующих массивов, используя маску, чтобы выбрать правильное значение:

program test 
    integer,parameter :: LENGTH=5 
    integer :: A(LENGTH) 
    integer :: B(LENGTH) 
    real :: R(LENGTH) 
    integer :: i 

    call random_number(R) 
    A = int(R*3) 
    B = [ (i,i=1,LENGTH) ] 

    print *,'A:',A 

    print *,'B:',B 
    B = merge(4, B, A == 2) 
    print *,'B:',B 
end program 

Выход:

A:   2   1   2   2   1 
B:   1   2   3   4   5 
B:   4   2   4   4   5 

Объяснение :

B = merge(4, B, A == 2) 
  • A == 2 создает временный логический массив, который является .true. в i, если A(i) == 2
  • 4 в этом случае представляет собой временный массив с той же длиной, как B
  • Итак, merge выбирает значение из 4 если временный логического массива .true., и соответствующее значение от B, в противном случае.
  • Результирующий вектор записывается обратно в B (=)