• ベストアンサー

最大公約数を求めたい!

二つの数字の最大公約数を求めたいのですがどうしたらいいのかわからず困っています…。プログラムに関しては初心者なのでどなたか分かりやすく教えてもらえませんか?? <さらにもし出来る方がおられたら…>------------------------------------ 実は最終的にはある数(a(素数))があって、そのaと”たがいに素”である数(b)をプログラムで求めたいんです…。 ある本によると適当な二つの素数p、qがあるとしてこのふたつの積(つまりp*q)をmとします。また、(p-1)(q-1)=aとすると ”gcd(b,a)≡1(mod m)” という式を満たすんだそうです…。 ※この中にでてくる値で実際に分からないのは"b"のみです。 ※ここで書いているgcd(b,a)というのはaとbの最大公約数のことです。 --------------------------------------------------------------------- かなり難しいのでこの質問の回答をいただくと本当に助かります。 よろしくお願いしますm(_ _)m

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

はじめまして。 私の持っている本に最大公約数を求めるサンプルマクロが載っておりましたので、お知らせいたします。私も試したところうまく動きましたので、間違えないかと思います。 Sub test() Dim iNum1 As Integer Dim iNum2 As Integer iNum1 = Val(InputBox("整数1は?")) iNum2 = Val(InputBox("整数2は?")) Do Until iNum1 = iNum2 If iNum1 > iNum2 Then iNum1 = iNum1 - iNum2 Else iNum2 = iNum2 - iNum1 End If Loop MsgBox Str(iNum1) End End Sub

ryuji0202
質問者

お礼

サンプルマクロありがとうございました! これなら代入する値を変えてそのままつかえそうですね(^^) 試してみます!

その他の回答 (3)

回答No.4

あなたのやりたいことは、このようなことでよろしいのでしょうか。 サンプルマクロを提示します。 Sub test() Dim iNum(1 To 4) As Integer Dim i As Integer iNum(1) = Val(InputBox("整数1は?")) For i = 1 To iNum(1) - 1 iNum(2) = iNum(1) iNum(3) = iNum(1) - i iNum(4) = iNum(3) Do Until iNum(2) = iNum(4) If iNum(2) > iNum(4) Then iNum(2) = iNum(2) - iNum(4) Else iNum(4) = iNum(4) - iNum(2) End If Loop If iNum(2) = 1 And iNum(3) > 1 Then MsgBox iNum(3) End If Next i End Sub わたしが、エクセル2000のVBAで実行したところ、お互いに素になる数を求めることができました。

ryuji0202
質問者

お礼

kazuhiko5681さん親切に再度ご回答していただいて本当にありがとうございます。 両方の回答を比べつつ私の作るプログラムに適した考え方を使っていこうと思います!!

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.3

○プログラムよりアルゴリズムの理解、決定(通常数種あってどれを使うべきか選択)が先です。本件ユークリッドの互助法の演習とすれば。 (あるいはユークリッドの互助法を直接使うなという演習かも) ○書いておられる定理のようなものは、概してコンピュターでは「直接」は使えません。難しすぎます。 ○下記で理解してください。下記URLの例の数を使った。   1523=1×814+709 (1523,814)=(814,709) (a,b)はaとbの公約数を表す記号とします。   理屈は下記に図示説明あり。  http://www.hokuriku.ne.jp/fukiyo/math-obe/euclid.htm   推移律的に(a,b)=(b,c)のcはbより小さくなります。 814=1×709+105 (814,709)=(709,105) 709=6×105+79 (709,105)=(105,79) 105=1×79+26 (105,79)=(79,26) 79=3×26+1 (79,26)=(26,1) 最大公約数は1です。   右辺の(b、c)のcが0の時は割りきれる訳ですから   bが最大公約数です。   右辺の(b、c)のcが1の時はこれ以上が割り算は続け (て意味なし)られないので1が最大公約数です。 (参考)http://web2.incl.ne.jp/yaoki/ansgcm.htm -----VBでの初等的解法 Sub gcd01() Dim a, b, gcd As Integer a = InputBox("a=") b = InputBox("b=(a>b)") '---- p01: c = a Mod b MsgBox "(" & a & "," & b & ")=(" & b & "," & c & ")" If c = 0 Then gcd = b GoTo p02: End If If c = 1 Then gcd = 1 GoTo p02 End If a = b b = c GoTo p01 '---- p02: MsgBox "gcd=" & gcd End Sub バグが無いことを祈りつつ。

ryuji0202
質問者

お礼

細かい説明を加えた回答ありがとうございました。 実際にVBで実行してみたところ、ちゃんと最終的に最大公約数を求めることができました!のせていただいたURLも参考にしたいと思います。

  • hinebot
  • ベストアンサー率37% (1123/2963)
回答No.2

かなりベタですが。 2つの数をa,bとします。 aをa,a-1,a-2,…,2 で順に割ってその余りをチェックします。余りが0であればそのとき割った数を覚えておきます。 ("順に割って"というのは、a/a, a/(a-1),a/(a-2),… という意味です) 同様のことをbについても行います。 aについて余りが0であった数とbについて余りが0であった数を比較し、共通なものをみつけ、その中で最大のものが最大公約数になります。 ※このアルゴリズムだとa,bが大きな数字の場合、かなり時間がかかりそうですが。 なお、aをa,a-1,a-2,…,2 で順に割ってその余りが0になるのものがa1つだけならば、その数aは素数です。

ryuji0202
質問者

お礼

回答ありがとうございました!! とても分かりやすく説明していただいたのでちゃんと理解することができました! これのプログラム化に挑戦してみたいと思います。

関連するQ&A

  • 最大公約数について

    「a,b,c,rが正の整数で、a=rb+cであるとき、a,bの最大公約数とb,cの最大公約数は一致することを証明せよ。」 という問題の解答の出だしが、 「aとbの最大公約数をm、bとcの最大公約数をnとおくと a=mA, b=mB(AとBは互いに素な整数) b=nB',c=nC(B'とCは互いに素な整数) と書ける」 となっているのですが、なぜこう書けるのかわかりません。 「a=mA, b=mB」「b=nB',c=nC」とかけるのはわかりますが、なぜAとB,B'とCが互いに素と言えるのかわかりません。 思いつく反例を上げると、a,b,cは異なる数とは問題文に書かれていないので、もしaとbが同じ数だとしたらA=Bとなり互いに素ではありませんよね?

  • a,bの最大公約数を求める関数をつくってみたのですが、aまたはbが零の

    a,bの最大公約数を求める関数をつくってみたのですが、aまたはbが零の時の処理としては、どのようにするのが適当かがわかりません。ある数と零の最大公約数ってどうなるんでしょうか? #include <iostream> using namespace std; // 整数 a, b の最大公約数を求める int gcd(int a, int b) { if(b == 0) return -1; // この戻り値は適当なのか? int r = a % b; // aをbで割った余り if ( r == 0 ) return b; // 余りが0ならbが最大公約数である else return gcd(b,r); // 余りが0でなければbとrの最大公約数を返す } int main() { cout << "gcd(1000,100) = " << gcd(1000, 100) << endl; return 0; }

  • 最大公約数を再帰で求める(pascal)

    入力した整数値の最大公約数を出力するプログラムを再帰呼び出しの形式で作れ、という課題が出ました。 再帰でない形式は下のように作れたのですが、再帰形式がどうしてもできません。どなたかご教授ください。 function gcd(a,b:integer):integer; {関数部} var tmp:integer; begin if a<b then begin tmp:=b; b:=a; a:=tmp end; repeat tmp:=b; b:=a mod b; a:=tmp until b=0; gcd:=a end; repeat {計算部、i=n=入力した個数、max=入力できる最大数} i:=i+1; n:=n+1; data[i]:=x; writeln('値:'); readln(x); until (x=0) or (i=max); if i>=2 then begin p:=gcd(data[1],data[2]); if i>=3 then begin for i:= 3 to n do begin p:=gcd(p,data[i]) end; writeln('最大公約数:',p) end else begin writeln('最大公約数:',p) end;

  • 最大公約数

    2つの正の整数をA、Bとし、AをBで割ったときの商をQ、あまりをRとすれば、A、Bの最大公約数はB、Rの最大公約数に一致するのはなぜですか?

  • 最大公約数

    ★a,bを自然数とする。a,bをa,bの最大公約数で割って得た商をそれぞれa',b'とするとき、それぞれa',とb'は互いに素であることを証明せよ。 という問題はどういう解法になるでしょうか? 素でないとしたら→a',b'がk*a'',k*b''と書けると思うんですが、素である場合はどう示せばよろしいでしょうか?

  • 最大公約数について教えてください!

    二つの整数m、n(m>n)の最大公約数をgとすると、mをnで割ったあまりとnとの最大公約数もgであることを証明せよ ただしm、nが互いに素であるとき、nとm-nも互いに素であることを使ってもよい 解説お願いします!

  • 最大公約数について!

    二つの整数m、n(m>n)の最大公約数をgとすると、mをnで割ったあまりとnとの最大公約数もgであることを証明せよ ただしm、nが互いに素であるとき、nとm-nも互いに素であることを使ってもよい はじめから解説をお願いします!

  • 最大公約数の証明

    a,b>1の時、gcd(a,b)=dならばgcd(a^2,b^2)=d^2となるのを説明せよ。 っていう問題で、説明の仕方がわかりません。 aが例えば2*3=6で、bが2*3*3=18だとすれば公約数は2*3で、aとbを2乗すると2^2*3^2と2^2*3^4になって共通なのは公約数の2乗になるからって・・・説明にもなってないようなことしか思い浮かびません・・・。 よろしくおねがいします。

  • 2^91-1と2^65-1の最大公約数

    2^91-1と2^65-1の最大公約数を求めるにはどうすればいいのですか? これほど大きな値だと共通の素数で割ることもユークリッドの互除法も使えそうにありません。 ちなみにコンピュータに解いてもらったら GCD(2^91-1,2^65-1)=8191 でした。

  • cはpとqの公約数で、dを最大公約数とします。

    cはpとqの公約数で、dを最大公約数とします。 ここで、最大公約数となる条件として 1)dで2つの整数pとqが割り切れる。 2)pとqのどんな公約数cでもdを割り切ることができる。 この関係を使って、c=p∧qで表すとします 例)p=18 q=12 とすると 18=1*2*3*3 12=1*2*2*3なので 公約数cは二つの共通部分 1 と 2(1*2より) と 3(1*3より) と 6(2*3より) となる ここで質問ですが、最大公約数dは d=max c つまりd=max{p∧q}で表すことはできますか? できれば証明をお願いしたいです>< 表すことができなければ、 p∧qを使って他に表す方法があれば教えてください。

専門家に質問してみよう