Почему этот код на Фортране не работает?

Эй, я написал это (fortran) с целью найти минимальное остовное дерево из множества точек (из них syscount). Я точно знаю, что этот подход работает, так как сегодня я написал его на javascript. js работает медленно, и я хотел посмотреть, насколько быстрее будет Фортран!! единственная проблема в том, что он не работает, я получаю раздражающую ошибку;

примс.f95:72.43:

if((check == 1) .and. (path(nodesin(j))(k) ‹ minpath)) тогда

                                 1

Ошибка: ожидалась правая скобка в выражении по адресу (1)

О чем это, черт возьми?! 43-й символ в строке — это «h» в слове «путь».

nodesin(1) = 1

do i = 1,syscount-1
    pathstart = -1
    pathend = -1
    minpath = 2000

    do j = 1,i
        do k = 1, syscount

            check = 1
            do l = 1, i
                if(nodesin(l) == k) then
                    check = 0
                end if
            end do

            if((check == 1) .and. (path(nodesin(j))(k) < minpath)) then
                minpath = path(nodesin(j))(k)
                pathstart = nodesin(j)
                pathend = k
            end if

        end do
    end do

    nodesin(i+1) = pathend
    minpaths(i)(1) = pathstart
    minpaths(i)(2) = pathend

end do

Кроме того, я новичок в фортране, поэтому у меня есть несколько других вопросов;

могу ли я использовать && вместо .and. ?

Существуют ли версии цикла for(object in list){} во многих других языках?

есть ли версия функции php in_array? то есть bool in_array(needle,haystack), и если есть, есть ли лучший способ сделать это, чем:

check = false
Asize = size(array)
do i = 1, Asize
    if(array(i) == needle) then
        check = true
    end if
end do

затем использовать проверочную переменную, чтобы увидеть, есть ли она?

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


person will    schedule 27.08.2010    source источник
comment
Можете ли вы использовать == в Фортране? В прошлый раз, когда я использовал его (Fortran 77 - я знаю, что мир с тех пор изменился), вы использовали .EQ. и .LT. и так далее. Я знаю, что Fortran 90 сильно модернизировался, но я не знаю, что это изменило. Попробуйте использовать .EQ., .LT., .LE., .NE., .GT., .GE. а также .И., .ИЛИ. и .НЕ. и посмотреть, поможет ли это. Классический язык Fortran, но, скорее всего, сработает.   -  person Jonathan Leffler    schedule 27.08.2010
comment
этот сайт: cs.mtu.edu/~shene /COURSES/cs201/NOTES/chap03/logical.html говорит, что == должно работать, кроме того, это работает несколькими строками выше, и если я изменю его, он просто сдвинет ошибку на 72,46. похоже проблема не в этом :-(   -  person will    schedule 27.08.2010
comment
Вы уверены в этом выражении path(nodesin(j))(k)? Что такое путь и узлы? Как они определены в коде?   -  person Wildcat    schedule 27.08.2010
comment
Если путь представляет собой двумерный массив, для доступа к его элементам следует использовать синтаксис пути (i, j), а не путь (i) (j).   -  person Wildcat    schedule 27.08.2010
comment
Является ли «чек» логическим значением? Если да, нужно ли вам использовать .FALSE. или .ИСТИНА. или их современные аналоги - или вам разрешено использовать 1? Так как сообщение жалуется на "1"... все еще ловит рыбу в темноте. Хотя ваш код иглы и стога сена предполагает, что проверка является BOOLEAN и что «ложь» и «истина» могут работать там, где 1 не работает?   -  person Jonathan Leffler    schedule 27.08.2010


Ответы (2)


Похоже, вы определили path и minpaths как двумерные массивы. Доступ к многомерным массивам в Fortran осуществляется иначе, чем в C-подобных языках. В Fortran вы разделяете индексы запятыми в одном наборе скобок.

Я предполагаю, что по использованию этих переменных они представляют собой целочисленные массивы. Вот как вы получаете доступ к элементам этих массивов (поскольку вы не делились своими объявлениями переменных, я составляю форму этих массивов):

integer :: path(n1, n2)
integer :: minpaths(n3, 2)

ваш оператор if должен быть:

if((check == 1) .and. (path(nodesin(j), k) < minpath)) then

ваш доступ к minpaths должен быть:

minpaths(i, 1) = pathstart
minpaths(i, 2) = pathend

Кроме того, если вы не используете IMPLICIT NONE, я рекомендую вам подумать об этом. Не использовать его опасно, и вы используете имена переменных, которые близки друг к другу (minpath и minpaths). Вы можете сэкономить часы на отладке, используя IMPLICIT NONE.

person brady    schedule 27.08.2010

В то время как .EQ. можно заменить на ==, там пока только .И.

Чтобы ваш блок кода проверял, существует ли «переменная», вы можете использовать «где» и получить гораздо более короткий код!

В Fortran >= 90 инструкций и функций могут работать с массивами, так что явные циклы не должны использоваться так часто.

Для (объекта в списке) нет, но с помощью оператора where можно сделать что-то очень похожее.

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

Я предлагаю прочитать книгу, чтобы узнать об этих функциях. Мне нравится произведение Меткалфа, Рида и Коэна. А пока может помочь вторая статья в Википедии: http://en.wikipedia.org/wiki/Fortran_95_language_features

person M. S. B.    schedule 27.08.2010