- 締切済み
関数化について
何度も質問しているんですがまた行き詰ってしまいました 以前解答をいただき自分なりに進めていき以下のことができるようになりました 1、多項式の係数を入力し、多項式(A)をつくる。 2、それを微分したもの(A’)で割る。→A÷A’=商・・・余りB 3、出てきた余り(B)を割る数、ひとつ前の作業で割る数だったもの(A’)を割られる数にする。 4、割る数(B)の最高次の係数の2乗をしたもの(a^2)を割られる数(A’)にかける。(擬除法) 5、割り算を行う。→(a^2)×A’÷B 6、余りが0になるまで3~5を繰り返す。(0にならなければ終わり) 7、割り切れたときの割る数がAとA’の最大公約数Dとなる(正確には最大公因数?) とここまでできるようになりました。 で、次にさらにまた 8、A÷D=E 9、DとEでユークリッドの互除法により最大公約数Gを求める 10、E÷G=P→PがAのi次の平方因子 11DをAとしDが無平方になるまで1~10を繰り返す。 といったことをやらなければいけないんですが、 いい加減関数を使わないと長すぎるので同じ作業を簡略化するため関数化することにしました。 で、微分のプログラムは関数化できたんですが、ユークリッドの互除法のプログラムが難しくて関数化できません。 わかる方お願いしますm(_ _)m 以下プログラム #include <stdio.h> #include <math.h> int main(void){ int m,m2,i,j,k,l,n,p,q; int a[1000],b[1000],c[1000],d[1000],e[1000]; puts("何次の多項式ですか?"); printf("何次:"); scanf("%d",&m); puts("多項式の係数を入力してください。"); for(i=m;i>=0;i--){ scanf("%d",&a[i]); //e[i]=a[i]; //printf("e[i]=%d\n",e[i]); } derivative(&m,a,&m2,b); printf("微分された多項式は:"); for(i=m2;i>=0;i--){ printf("%dx^%d+ ",b[i],i); } printf("\n\n"); q = 1; l = 0; while(q == 1){ printf("割られる数は:"); for(i=m;i>=0;i--){ a[i]=a[i]*(b[m2]*b[m2]); printf("%dx^%d + ",a[i],i); } q = 0; printf("\n上のは割る数の最高の次数の係数の2乗をかけたもの:b[m2]=%d\n",b[m2]); printf("--\n"); printf("%d回目の商は\n",l+1); for(k=m-m2;k>=0;k--){ c[k] = a[m - (m - m2 - k)] / b[m2]; printf("%dx^%d + ",c[k],k);//商の表示 j = m2; for(i = m - (m - m2 - k);i>= m - (m - m2 - k) - m2 ;i--){ d[i]=a[i]-c[k]*b[j]; a[i] = d[i]; j = j - 1; } } printf("\n"); for (k = m2;k >=0 ;k--){ a[k] = b[k]; } printf("余り:"); for (k = m2-(m-m2);k >=0 ;k--){ b[k] = d[k]; printf("%dx^%d + ",b[k],k); if (d[k] != 0){ q = 1; } } for (k = 0;k <= 1000;k++){ d[k] = 0; } printf("q:%d\n",q); p = m2 - 1; m = m2; m2 = p; l = l + 1; printf("\n"); while(b[m2] == 0){ m2 = m2 - 1; } if (m2 <= 0){ break; } } if (q == 0){ printf("割り切れた"); }else{ printf("割り切れなかった"); } return(0); } int derivative(int *m, int a[],int *m2, int b[]) { int i; for(i=*m;i>0;i--){ b[i-1]=i*a[i]; } *m2=*m-1; return(0); }
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- WizTaka
- ベストアンサー率53% (7/13)
>>int GetGreatestCommonDivisorByEuclideanAlgorithm(int a, int b) >関数名が長すぎるし、実装方法まで名前に入れてしまうのはどうかと思います。 忠告がとっても親切ですね☆ まったくごもっともな意見です. 確かに自分でプログラム書くとき (仕事とか) では絶対しません. 「この方が親切かなぁ?」と,敢えてこうしました. この大きなお世話が逆に opossamu さんに失礼だったかも... 誠に申し訳ない... ってか,仕事でこんなん書いたらどつかれる. "ByHogeHoge" とか絶対あり得ないw この場合,最大公約数を GCD と書いて誰が見ても一瞬で分かるのなら, int GetGCD(int a, int b) なんかに落ち着かせるところですね. koko_u_ の言うとーり,これからはその辺の不要なお世話はしないようにします. どーもありがとうm(_ _)m (けど質問に答えるよりもそこを突っ込んでくるなんて,間違ったことを教えたくない程プログラミングを愛しているんですね)
- koko_u_
- ベストアンサー率18% (459/2509)
多項式なんですよね。 まずは関数の宣言をどうするか考えて補足にどうぞ。 >int GetGreatestCommonDivisorByEuclideanAlgorithm(int a, int b) 関数名が長すぎるし、実装方法まで名前に入れてしまうのはどうかと思います。
- WizTaka
- ベストアンサー率53% (7/13)
while 文の中をもう少し綺麗に書いてみました. //------------------------------------------------------------- int GetGreatestCommonDivisorByEuclideanAlgorithm(int a, int b) { if(a < b) ::swap(a, b); if(b == 0) return a; while(true) { a = a % b; if(a == 0) break; ::swap(a, b); } return b; } //-------------------------------------------------------------
- WizTaka
- ベストアンサー率53% (7/13)
ユークリッド互除法の関数化ですが,Wikipedia の "ユークリッドの互除法" に書いてあるアルゴリズムをそのまま関数にしてみました. 一例ですが,以下のような感じでどうでしょうか? ※C++ の文法で書いてますが,雰囲気は十分に分かっていただけると思います. Wikipedia "ユークリッドの互除法" http://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%AF%E3%83%AA%E3%83%83%E3%83%89%E3%81%AE%E4%BA%92%E9%99%A4%E6%B3%95 //------------------------------------------------------------- int GetGreatestCommonDivisorByEuclideanAlgorithm(int a, int b) { if(a < b) ::swap(a, b); if(b == 0) return a; while(true) { if(a % b == 0) break; else { a = a % b; ::swap(a, b); } } return b; } //-------------------------------------------------------------