最大公約数と最小公倍数を求めるプログラム

このQ&Aのポイント
  • C言語で2つの整数の最大公約数と最小公倍数を求めるプログラムをご紹介します。
  • その中でも最小公倍数を求める方法を説明します。
  • また、自然数n以下でx^2+y^2=z^2を満たす自然数の組(x,y,z)を求めるプログラムについてもお教えします。
回答を見る
  • ベストアンサー

このプログラム見てほしいです!!

#include <stdio.h> int gcd2(int a, int b) { if (!b) return a; return gcd2(b, a%b); } int main() { int a, b, c; printf("2つの任意の整数を入力せよ:"); scanf("%d %d",&a,&b); c=gcd2(a,b); printf("最小公倍数は%d\n",a*b/c); printf("最大公約数は%d\n",c); return 0; } で、最小公約数を出すことはできたのですが、全ての公約数を表示させたいんです!!どうやったらいいのでしょうか??プログラミングまだ初心者なので、ちょっと行き詰ってしまいました。。。 お時間があればでいいのですが、もう一つわからないプログラムがあります。 自然数nを入力し、x^2+y^2=z^2 (x<y)を満たすようなn以下の自然数の組(x,y,z)がいくつあるのかを出力するプログラムなのですが、全くわからず行き詰っています。。どなたかお時間があれば教えて頂きたいです。 色々と申し訳ありません。お願いします(__)

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

本当は、もっと使い回しの利くように作ればいいんでしょうが… とりあえず、#1で言っていることをプログラムにしたものです。 #include <stdio.h> void main(void){ int a,b; int x,y; int i; /* a と b の共通の約数を求める */ a=156; b=768; if(a>b){ /* x<=yにする */ x = b; y = a; } else { x = a; y = b; } printf("%d と %d の共通約数は、",a,b); for(i=1;i<=x;i++){ if(x % i == 0){/* i は、x の約数 */ if(y % i == 0){/* i は、y の約数でもある */ printf("%d ",i); } } } }

spider1984
質問者

補足

for(i=1;i<=x;i++){ if(x % i == 0){/* i は、x の約数 */ if(y % i == 0){/* i は、y の約数でもある */ printf("%d ",i); このforの中でprintfを表示させることで、全ての公約数を表示させることができるとゆうことですかね?? あと、 if(x % i == 0) if(y % i == 0) の部分は if(x % i == 0)&&(y % i == 0) でも良いのでしょうか??

その他の回答 (6)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.7

#2>このforの中でprintfを表示させることで、全ての公約数を表示させることができるとゆうことですかね?? まあ、そうだと思いますけど・ 表示させたいということだったので表示しているので、必要充分かと・ 使い回しが利くようにするには、可変長のデータを保持できるような(例えばリストのような)データ構造が必要かと思いますが、それは、また別の話。 #2>if(x % i == 0)&&(y % i == 0) そうですね。 if((x % i == 0)&&(y % i == 0)) で動作は同じになると思います。 xのテストが左に書いてあるのがミソで、同じようでも if((y % i == 0)&&(x % i == 0)) だと動作が変わってしまうので注意が必要です。 ポイントは、x % i == 0の時だけy % i == 0が評価される(計算される)というところですね。 C言語では、そういう動作が期待できますが、そういう動作をしない言語処理系もあるかもしれません。 まあ、意味をはっきりさせる意味で、ああしています。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.6

#5は間違い /* x^2+y^2=z^2 (x<y)を満たすようなn以下の自然数の組(x,y,z)がいくつあるか? */ #include <stdio.h> #include <math.h> void main(void){ unsigned long x,y,z,n; unsigned long x2,wk; unsigned limit,c; n=100;c=0; limit = n/sqrt(2.0)+1;/* A^2+A^2<=N^2 → A< N/√2 + 1 */ for(x=1;x<limit;x++){ x2=x*x; for(y=x+1;y<n;y++){ z=sqrt(wk=x2+y*y)+0.5; if(z<=n && wk==z*z){ printf("(x,y,z)=(%lu,%lu,%lu)\n",x,y,z); c++; } } } printf("計:%lu組\n",c); }

spider1984
質問者

お礼

色々とありがとうございます!!

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

/* x^2+y^2=z^2 (x<y)を満たすようなn以下の自然数の組(x,y,z)がいくつあるか? */ #include <stdio.h> #include <math.h> void main(void){ unsigned long x,y,z,n; unsigned long x2,wk; unsigned limit,c; n=100;c=0; limit = n/sqrt(2.0)+1;/* A^2+A^2<=N^2 → A< N/√2 + 1 */ for(x=1;x<=limit;x++){ x2=x*x; for(y=x+1;y<=limit;y++){ z=sqrt(wk=x2+y*y)+0.5; if(wk==z*z){ printf("(x,y,z)=(%lu,%lu,%lu)\n",x,y,z); c++; } } } printf("計:%lu組\n",c); }

回答No.4

#3です。間違いだらけです・・・ GCM=1のときに互いに疎です。ハイ。 nがごっちゃになっていてわかりづらいです。これも申し訳アリマセン。書き直しました・・・ n以下のピタゴラス数を求めるんですね? ピタゴラス数はα,βが互いに疎で一方が偶数、一方が奇数(α>β)のとき、 α^2+β^2、α^2-β^2、2αβで表されるけど、α,βが互いに疎かどうかをGCMを求めて判定しているんですよね?? α,βを適当に決めて(総当りで)α,βのGCMを求めて、GCM=1のとき上記3式を計算すればピタゴラス数(x,y,z)が出ます。 ちなみにx<y<zの関係があります。 再度その3数x,y,zがある数n以下かどうかを判定し、マッチしていれば表示していけばよいです。

回答No.3

n以下のピタゴラス数を求めるんですね? ピタゴラス数はm,nが互いに疎で一方が偶数、一方が奇数(m>n)のとき、 m^2+n^2,m^2-n^2,2mnで表されるけど、m,nが互いに疎かどうかをGCMを求めて判定しているんですよね?? m,nを適当に決めて(総当りで)m,nのGCMを求めて、GCM>1のとき上記3式を計算すればピタゴラス数が出ます。 再度その3数がある数以下かどうかを判定し、マッチしていれば表示していけばよいです。 私はそうやって「ピタゴラス星雲」を描きました!

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

>全ての公約数 AとBの数字のうち小さい方をXとして、 Xの約数を求める、 求めた約数のウチもう一方の約数になっているか調べる。 なっていたら、公約数。 n以下の自然数の組 n以下の意味は、 x,y,zそれぞれが0<X≦nの意味ですか それとも x+y+z≦nの意味?

spider1984
質問者

補足

>全ての公約数 意味はわかるのですが、printf()の中身など、どうやって全ての約数を表示させるのかがいまいちわかりません。scanfでばらばらの数値を入れるので公約数がいくつ出てくるのかもわからないので。。プログラムで書くとどうゆう風になるかが検討がつかなくて。。 x,y,zそれぞれが0<x,y,z≦nの意味です!

関連するQ&A

  • 2つ分数の四則演算を行うプログラム

    <要求事項> 分数は、 例)1|3 のように表す。 1.分母がゼロの時はエラーとする。 2.除算において、除数がゼロの入力エラーに対しては、再入力するように促す。 3.以下範囲の整数(分子、分母にかかわらず)に対して、正しく計算できるようにする。   -2147483648 ~ 2147483647 4.計算結果については,分母が1の時には分子のみ表示。分数がの時には0のみを表示。最終計算結果は既約分数にする。分数が負数の場合、-を分数の前に表示。 #include <stdio.h> #include <math.h> int main(void) { int b,d; /* 分母*/ int a,c; /* 分子*/ int sign,sign2,sign3,sign4; int yakusu,yakusu2,yakusu3,yakusu4; /* 最大公約数*/ printf("分母= "); scanf("%d",&b); printf("分子= "); scanf("%d",&a); if(b==0){ printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/ return 0; } if (a==0){ printf("分数1= 0\n"); /*分子が0のとき*/ } else{ printf("分数1=%d|%d\n",a,b); /*一つ目の分数*/ } printf("\n"); printf("分母= "); scanf("%d",&d); printf("分子= "); scanf("%d",&c); if(d==0){ printf("分母が0です。入力が誤っています。\n"); /*分母が0ならエラーとする*/ return 0; } if (c==0){ printf("分数2= 0\n"); /*分子が0のとき*/ } else{ printf("分数2=%d|%d\n",c,d); /*二つ目の分数*/ } printf("\n"); /* 足し算:a|b + c|d = (a*d + b*c) | (b*d) */ printf("足し算:%d|%d + %d|%d\n",a,b,c,d); yakusu = gcd(abs(a*d + b*c),abs(b*d)); /*最大公約数を求める*/ sign = (a*d + b*c)/abs(a*d + b*c) * (b*d/abs(b*d)); if(sign * abs(a*d + b*c)/yakusu == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu!= 1){ printf("既約分数は %d|%d\n" ,sign * abs(a*d + b*c)/yakusu , abs(b*d)/yakusu ); } else{ printf("既約分数は %d\n" ,sign * abs(a*d + b*c)/yakusu ); /*分母が1の場合*/ } printf("\n"); /* 引き算:a|b - c|d = (a*d - b*c) | (b*d) */ printf("引き算:%d|%d - %d|%d\n",a,b,c,d); yakusu2 = gcd(abs(a*d - b*c),abs(b*d)); /*最大公約数を求める*/ sign2 = (a*d - b*c)/abs(a*d - b*c) * (b*d/abs(b*d)); if(sign2 * abs(a*d - b*c)/yakusu2 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu2!= 1){ printf("既約分数は %d|%d\n" ,sign2 * abs(a*d - b*c)/yakusu2 , abs(b*d)/yakusu2 ); } else{ printf("既約分数は %d\n" ,sign2 * abs(a*d - b*c)/yakusu2 ); } printf("\n"); /* 掛け算:a|b * c|d = (a*c) | (b*d) */ printf("掛け算:%d|%d * %d|%d\n",a,b,c,d); yakusu3 = gcd(abs(a*c),abs(b*d)); /*最大公約数を求める*/ sign3 = (a*c)/abs(a*c) * (b*d/abs(b*d)); if(sign3 * abs(a*c)/yakusu3 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*d)/ yakusu3!= 1){ printf("既約分数は %d|%d\n" ,sign3 * abs(a*c)/yakusu3 , abs(b*d)/yakusu3 ); } else{ printf("既約分数は %d\n" ,sign3 * abs(a*c)/yakusu3 ); /*分母が1の場合*/ } printf("\n"); /* 割り算:a|b / c|d = (a*d) | (b*c) */ printf("割り算:%d|%d / %d|%d\n",a,b,c,d); yakusu4 = gcd(abs(a*d),abs(b*c)); /*最大公約数を求める*/ sign4 = (a*d)/abs(a*d) * (b*c/abs(b*c)); if(sign4 * abs(a*d)/yakusu4 == 0){ /*分子が0となる時*/ printf("0\n"); } if (abs(b*c)/ yakusu4!= 1){ printf("既約分数は %d|%d\n" ,sign4 * abs(a*d)/yakusu4 , abs(b*c)/yakusu4 ); } else{ printf("既約分数は %d\n" ,sign4 * abs(a*d)/yakusu4 );/*分母が1の場合*/ } return 0; } int gcd(int x,int y){ /* ユークリッド互除法*/ int z; if( (x <= 0) || (y <= 0) ){ return -1; } z = x % y; while (z != 0){ x = y; y = z; z = x % y; } return y; } >>大学の課題です。現在の状態は上記の通りです。このプログラムだと、答えの既約分数が0になると表示できなかったり、桁が大きい数で計算しようとすると値がおかしくなってしまいます。 どなたかプログラム改良にご助力願えないでしょうか?

  • 既約分数の表示プログラム

    (1)キーボードから,分子,分母に相当する整数2つを入力し,その既約分数を表示せよ。 (2)分母が1の時には,分子のみを表示する。 (3)分子と分母の符号が異なるときにのみ,-符号を表示する。 (4)分母がゼロの入力エラーに対しては、再入力するように促す。 (5)分子と分母の最大公約数も求めて表示する。 (6)また、正しく計算できる最大規約分数を示せ。 #include <stdio.h> int main(void) { int a,b,i=1,x,y,z; printf("分子=");/*分子の入力*/ scanf("%d",&a); printf("分母=");/*分母の入力*/ scanf("%d",&b); if(b==0) { printf("分母が0です。入力が誤っています。\n"); return 0; } if(b==1) { printf("既約分数は %d\n",a); return 0; } while((i<=a)&&(i<=b)) { if((a%i==0)&&(b%i==0)) { x=i;i=i+1; /*xを上書きしていく*/ } else { i=i+1; } } printf("分子と分母の最大公約数=%d より\n",x); y=a/x; z=b/x; printf("既約分数は %d/%d\n",y,z); return 0; } 大学の課題で出されたものです。(1)(2)(4)(5)はできたのですが、(3)と(6)の部分のやり方がいまいちよくわからなかったので質問しました。 どなたかご教授お願いできないでしょうか・・・。

  • C言語の問題です

    二つの仮分数の加算を行うプログラミングである。 x/w+z/y=(xy+wz)/(wy) 1. w,x,y,zは正の整数である。 2.上式のように計算した後、約分して結果を求める。約分には最大公約数を使う。最大公約数の計算は関数gcd(a,b)で以下のアルゴリズム(ユークリッド互除法)で行う。 (1) a,bの大きいほうをp,小さいほうをqとする。 (2) pをqで割った余りをrとする。r=0ならqが解。 r≠0なら、q=r、r=qとして(2)に戻る。 3.計算結果が仮分数ならば、帯分数にして出力する。 次のプログラムの空欄((1)から(3):を埋め、完成させて下さい。 #include <stdio.h> int gcd(int a, int b) { int p,q,r; if(a<b) { q=a; p=b; }else{ q=b; p=a; } while(q>0){ (1); p=q; q=r; } (2); } main(){ int g,k,m,n,p,q,w,x,y,z; printf("x/w + z/yの数値を入力して下さい(x w z y)"); scanf("%d %d %d %d, &x,&w,&z,&y"); m= w*y; n=x*y+w*z; p=m; q=n; g=gcd(p,q); m=m/g; n=n/g; if((3)) { k = n/m; n = n - k*m; if(n==0) printf("%d\n",k); else printf("%d %d/%d\n",k,n,m); } else printf("%d/%d\n",n,m); } 全く見当がつきません。どなたかお助け下さい。回答を教えてください。

  • 学校の課題で2次方程式のプログラムを作ってみたのですが、足りない部分ががあるらしいのでお教えてください

    キーボードからある整数の値を入力して、2次方程式を解くというプログラムを作ったのですが、解の方程式のところでどこかが足りないらしいのですが教えてください。 #include<math.h> #include<stdio.h> int quadraticEquation(double a, double b, double c){ int x,y,l,k,j; double z; x=b*b; y=4*a*c; z=x-y; if(z>=0){ l=sqrt((double)z); } else printf("ERROR!!\n"); k=(-b)+l; j=k/2*a; return j; } int main(void){ int n1,n2,n3; printf("input three integer!\n"); printf("intger1:"); scanf("%d",&n1); printf("intger2:"); scanf("%d",&n2); printf("intger3:"); scanf("%d",&n3); printf("kotaeha %d %d desu\n",quadraticEquation(n1, n2, n3),quadraticEquation(n1, n2, n3)); return 0; } が自分が作ったプログラムです。 後、解が2つある場合の出力方法がこれであっているかどうかも教えてください。 よろしくお願いします。

  • 参照による呼び出し

    参照による呼び出しで3つの整数を大きい順に並び替えるという プログラムで、 #include<stdio.h> void change(int *x,int *y,int *z);/       main(){ int a,b,c; scanf("%d %d %d",&a,&b,&c); printf("入力データ:a=%d,b=%d,c=%d\n",a,b,c); change(&a,&b,&c); printf("入れ替え後:a=%d,b=%d,c=%d\n",a,b,c); return(0); } void change(int *x,int *y,int *z){ if(*x>*y){ *a=*x; *c=*y; } else{ *a=*y; *c=*x; } if(*z>*a){ *b=*a; *a=*z; } else if(*z>*c){ *b=*z; } else{ *b=*c; *c=*z; } } のように作ったのですが、zの値が一度も使われていないとエラーが 出てしまいます。どこをどう直せばいいか教えてください。 お願いします。

  • 関数のプログラムについて

    任意の二次方程式ax^2+bx+c=0をとくプログラムの作成です 引数をa,b,cとして、解の大きい方を返すというものなのですが、 僕は以下のようにして組んだのですが、うまくいきません。 と、いうより、関数の作り方がいまいちわからないです。 どこが駄目なのか教えてください。 作ってみたやつ↓ #include<math.h> #include<stdio.h> int a,b,c; double d; double x,y,z; int main(void) { a=1; b=2; c=1; printf("ax^2+bx+c=0\n "); d=b^2-4*a*c; if (d<0){printf("kyosuukai\n)} else if(d>=0) { x=(b+sqrt(b^2-4*a*c))/2*a; y=(b-sqrt(b^2-4*a*c))/2*a; if(x>=y){z=x} else if(x<y){z=y} printf("x= %f\n",z); } }

  • わかりません・・・。

    二つの自然数を引数として与えられて,それらの最大公約数を返す関数 int gcd(int m, int n) { /* … */ }を作成し,それを利用して入力された二つの正整数の最大公約数を求めるプログラムを作り方を教えてください。 ユークリッドの互除法を使い、関数を使う事が条件なのですが全然わかりません。 #include<stdio.h> int gcd(int m, int n) if(m>n) {m%n}            if(m%n==0) printf("最大公約数は%d",n); ←このあたりがわかりません else if (n%(m%n)) printf("最大公約数は%d",n%(m%n)); int main( void ) { int na, nb; puts(""二つの整数を入力してください。); printf("整数1:"); scanf("%d",na); printf("整数2:"); scanf("%d",nb); printf("最大公約数は%dです。\n",gcd(int m, int n)); return0; }

  • プログラムに詳しい方教えてください!

    #include<stdio.h> void fxl(int x,int y); int main(void) { int a,b,m,n; printf("整数aの値を入力\n"); scanf("%d",&b); printf("整数bの値を入力\n"); scanf("%d",&b); m=a; n=b; fxl(m,n); printf("a=%dとb=%dを加算した値は%d\n",ab,m); printf("a=%dからb=%dを減算した値は%d\n",ab,n); return 0; } void fxl(int x,int y) { int j,k; j=x; k=y; x=j+k; y=j-k; } このプログラムを作ってみたのはいいのですが、参照渡しを使って正常に足し算、引き算をするにはどうすればよいのでしょうか。

  • 有理数の演算についてなんですが。。

    #include <stdio.h> typedef struct{ int bunshi; int bunbo; }rat; rat rat_num(int x,int y){ rat r; r.bunshi=x; r.bunbo=y; return(r); } void rat_print(rat x){ printf("%d/%d,"x.bunshi,x.bunbo); } int gcd(int n, int m) { int res; res = n % m; if (res == 0) return m; return gcd(m, res); } rat rat_normalize(rat x){//ここです** } rat rat_plus(rat x, rat y){ //足し算 } int main() { rat x={1,3}; rat y={3,4}; rat z; z=rat_plus(x,y); printf("1/3+3/4= ");rat_print(z);printf("\n"); } 分数の足し算のプログラムをつくりたくてだいたいのそと枠はできたのですが int gcd(int n, int m)のところではnとmの最大公約数を求めるものでたぶんここはできていると思うのですが、rat rat_normalize(rat x)のところでxを約分して返す。(x.bunshiとx.bunboをそれらの最大公約数で割る)っていうことをしたいんですけど、構造体を勉強しはじめたばかりでどのように書いたらよいかわかりません。教えてください。 rat rat_plus(rat x, rat y){ //足し算 }のところはそこがわかればできそうなので大丈夫です!! お願いします><

  • このプログラムの間違いを指摘していただけませんか?

    まだ、初めて一ヶ月も経たない者です。それでも、勉強しつつ、組んでみたのですが、うまくいきません。数字の足し算をして、結果を表示させたいのですが、四回足しても四回目の数字が、足されずに結果がでてしまいます。1と2と3と4と入力すると、6と出てきます。一体どのようにしたらよいのでしょうか?教えて頂けませんか?(下に書いてあります。) #include <stdio.h> int sub(int x, int y, int z){ return x + y + z; } int main() { int i; int a[i]; for (i=1; i<=1; ++i){ printf("数字は?\n"); scanf ("%d\n", &a[i]); scanf ("%d\n", &a[i+1]); scanf ("%d\n", &a[i+2]); scanf ("%d\n", &a[i+3]); int result,x,y,z; result = sub(a[i],a[i+1],a[i+2]); printf("結果は%d\n",result); } return 0; }

専門家に質問してみよう