2013-05-16 4 views
1

Я хотел бы решить данное уравнение следующего вида с Fortran:магазин арифметические операции в массиве с Fortran

1 ? 2 ? 3 = 7 

В этом уравнении только арифметические операторы не хватает, и решение будет «+» для первого вопросительного знака и '*' для второго. Я хотел бы написать короткий скрипт, который находит правильные операторы грубой силой. Поэтому в этом случае необходимо будет проверить четыре раза четыре случая. Для того, чтобы сделать это, я хотел бы хранить операторы в массиве и использовать их в вложенным сделать петлю:

value1=1 
    value2=2 
    value3=3 
    result=7 

    op(1)=+ 
    op(2)=- 
    op(3)=/ 
    op(4)=* 

    do i=1,4 
     do j=1,4 
      if(value1 op(i) value2 op(j) value3 .eq. result) then 
      write(*,*)'Found solution: ' ,op(i), op(j) 
      else 
      j=j+1 
      endif 
     enddo 
    i=i+1 
    enddo 

Видимо, это не работает из-за неправильной интерпретации, если-заявление. Любые идеи, как сделать эту работу?

ответ

1

Это не может быть сделано в Фортране. Какой тип вы заявили для op? Нет такого, что подойдет. Одна вещь, которую вы можете сделать, это определить некоторые функции и сохранить в них указатели на объекты.

4

Как Vladimir pointed out, вы не можете сделать это напрямую в Fortran, если не используете указатели на функции. Ниже вы найдете пример.

Я сделал это простым, используя только целые операции. Также обратите внимание, что я предположил, что операции в вашем выражении выполняются слева направо (без правил приоритета), иначе алгоритм будет намного сложнее. Если приоритет имеет значение, вы должны подумать об использовании интерпретируемого языка для задачи (если только скорость выполнения не является критической).

Здесь модуль определение операций и типа, содержащие процедуры указателей:

module myfuncs 
    implicit none 

    abstract interface 
    function binary(i1, i2) 
     integer, intent(in) :: i1, i2 
     integer :: binary 
    end function binary 
    end interface 

    type :: procptr 
    procedure(binary), pointer, nopass :: ptr 
    end type procptr 

contains 

    function add(i1, i2) result(res) 
    integer, intent(in) :: i1, i2 
    integer :: res 
    res = i1 + i2 
    end function add 

    function mul(i1, i2) result(res) 
    integer, intent(in) :: i1, i2 
    integer :: res 
    res = i1 * i2 
    end function mul 

    function sub(i1, i2) result(res) 
    integer, intent(in) :: i1, i2 
    integer :: res 
    res = i1 - i2 
    end function sub 

    function div(i1, i2) result(res) 
    integer, intent(in) :: i1, i2 
    integer :: res 
    res = i1/i2 
    end function div 

end module myfuncs 

Вот главная программа с перебором:

program bruteforce 
    use myfuncs 

    type(procptr) :: ops(4) 
    character :: opnames(4) 
    integer :: val1, val2, val3, res, myres 

    val1 = 1 
    val2 = 2 
    val3 = 3 
    res = 7 

    ops(1)%ptr => add 
    ops(2)%ptr => sub 
    ops(3)%ptr => mul 
    ops(4)%ptr => div 
    opnames = [ "+", "-", "*", "/" ] 

    lpi: do ii = 1, 4 
    lpj: do jj = 1, 4 
     myres = ops(jj)%ptr(ops(ii)%ptr(val1, val2), val3) 
     write(*,"(3(I0,1X,A,1X),I0)") val1, opnames(ii), val2, & 
      &opnames(jj), val3, " = ", myres 
     if (myres == res) then 
     write(*,*) "Solution found." 
     exit lpi 
     end if 
    end do lpj 
    end do lpi 

end program bruteforce 
+0

Большого спасибо за вашу работу! Хотя, я боюсь, что мне придется рассмотреть вопрос о соблюдении правил. Кроме того, я на самом деле хотел решить не более двух уравнений работы (до 7). Поэтому, может быть, мне следует переключиться на другой язык, как вы предложили. Есть ли у вас какие-либо конкретные предложения по языку, который подходит для этой проблемы и с которым легко справиться? – user2390654

+0

Все это прекрасно, что дает конструкцию, похожую на eval(), способную оценить строку, содержащую допустимое выражение на этом языке. Если вы уже знаете такой язык, возьмите это. В противном случае Python или Ruby могут быть возможными вариантами, где в моем (определенно * предвзятом *) оппонировании бывший несколько ближе в своей философии к Fortran, поэтому для вас может быть упрощено. Но просто взгляните на них и решите сами. –

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