【问题标题】:Store arithmetic operators in an array with Fortran使用 Fortran 将算术运算符存储在数组中
【发布时间】:2013-05-16 15:51:39
【问题描述】:

我想用 Fortran 求解以下类型的给定方程:

1 ? 2 ? 3 = 7

在这个等式中,只有算术运算符缺失,第一个问号的解是“+”,第二个问号是“*”。我想写一个简短的脚本,通过蛮力找到正确的运算符。因此,在这种情况下,必须检查四次四次。为了做到这一点,我想将运算符存储在一个数组中并在嵌套的 do 循环中使用它们:

    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

显然,由于对 if 语句的错误解释,这不起作用。任何想法如何使这项工作?

【问题讨论】:

    标签: variables fortran operator-keyword


    【解决方案1】:

    作为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
    

    【讨论】:

    • 非常感谢您的工作!不过,恐怕我将不得不考虑优先规则。此外,我实际上想解决的不仅仅是两个运算方程(最多 7 个)。所以,也许我应该按照您的建议切换到另一种语言。对于适合此类问题且易于处理的语言,您有什么特别的建议吗?
    • 所有这些都很好,它们提供了类似 eval() 的构造,能够评估包含该语言的有效表达式的字符串。如果你已经知道这样一种语言,那就拿去吧。否则 Python 或 Ruby 可能是可能的选择,在我(绝对偏向)的观点中,前者在其哲学上更接近 Fortran,因此您可能更容易学习。但只要看看它们并自己决定。
    【解决方案2】:

    这不能在 Fortran 中完成。你为op 声明了什么类型?没有合适的。您可以做的一件事是定义一些函数并存储指向它们的函数指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多