0

如何编写一个gcd(x : Integer, y : Integer) : Integer返回两个正整数的最大公约数的运算(将它们完全除的最大整数)ocl

4

1 回答 1

0

这是一个简单的解决方案(当然不是有效的,但它有效):

let divs : Sequence(Integer) = if x < y then Sequence{1..y} else Sequence{1..x} endif
in divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()

简单地做的是生成每个潜在候选者的序列,然后,从这个序列中,只有那些被划分x并被y选择并存储在一个新序列中(这是有序的)。最后,这个过滤序列的最后一个数字是你的最大公约数。

现在详细说明:

  1. 我们产生一个序列Sequence{a..b}
  2. 这个序列是从到和( )1之间的较大数字xyif x < y then Sequence{1..y} else Sequence{1..x}
  3. 此序列存储在不可变变量divs( let divs : Sequence(Integer) = ... in ...)中
  4. divs中,我们只z选择xz(divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)
  5. 最后,我们只取新序列中的最后一个元素 ( select(...)->last())

如果last()你的环境中不存在该函数(不知道为什么,但是一些 OCL 实现自带了函数),你可以使用:

->sortedBy(i | -i)->at(1)

而不是last(),它反转序列并获取第一个元素。

编辑>

您也可以通过这种方式减少表达式:

let divs : Sequence(Integer) = Sequence{1..x.max(y)}
in divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()

或者,通过删除使用divs

Sequence{1..x.max(y)}->select(z | x.mod(z) = 0 and y.mod(z) = 0)->last()
于 2016-06-17T06:38:51.880 回答