gcd(x : Integer, y : Integer) : Integer
2 つの正の整数 (両方を正確に割る最大の整数) の最大公約数を返す演算を でどのように記述できocl
ますか?
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
選択され、新しいシーケンスに格納されます (順序付けられます)。最後に、このフィルター処理されたシーケンスの最後の数値が最大公約数です。
詳細は次のとおりです。
- でシーケンスを生成します
Sequence{a..b}
- このシーケンスは からと( )
1
の間の大きい方の番号になります。x
y
if x < y then Sequence{1..y} else Sequence{1..x}
- このシーケンスは、不変変数
divs
(let divs : Sequence(Integer) = ... in ...
)に格納されます。 - からと(
divs
_z
_x
z
divs->select(z | x.mod(z) = 0 and y.mod(z) = 0)
- 最後に、新しいシーケンスから最後の要素のみを取得します (
select(...)->last()
)
関数がenvに存在しない場合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 に答える