ocl中的最大公约数
greatest common divisor in ocl
如何写一个操作gcd(x : Integer, y : Integer) : Integer
returns ocl
中两个正整数的最大公约数(能整除它们的最大整数)?
这里有一个简单的解决方案(当然无效,但有效):
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
相除的 selected 和存储在一个新序列中(已排序)。最后,此过滤序列的最后一个数字是您的最大公约数。
现在详细介绍:
- 我们用
Sequence{a..b}
生成一个序列
- 这个序列是从
1
到 x
和 y
之间的较大数字 (if x < y then Sequence{1..y} else Sequence{1..x}
)
- 这个序列存储在一个不可变变量中
divs
(let divs : Sequence(Integer) = ... in ...
)
- 从
divs
,我们select只有数字z
,它是x
和z
的约数(divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)
- 最后,我们只取新序列的最后一个元素 (
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()
如何写一个操作gcd(x : Integer, y : Integer) : Integer
returns ocl
中两个正整数的最大公约数(能整除它们的最大整数)?
这里有一个简单的解决方案(当然无效,但有效):
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
相除的 selected 和存储在一个新序列中(已排序)。最后,此过滤序列的最后一个数字是您的最大公约数。
现在详细介绍:
- 我们用
Sequence{a..b}
生成一个序列
- 这个序列是从
1
到x
和y
之间的较大数字 (if x < y then Sequence{1..y} else Sequence{1..x}
) - 这个序列存储在一个不可变变量中
divs
(let divs : Sequence(Integer) = ... in ...
) - 从
divs
,我们select只有数字z
,它是x
和z
的约数(divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)
- 最后,我们只取新序列的最后一个元素 (
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()