C言語関係掲示板

過去ログ

No712 1!〜53!の階乗値を配列を使って求めて、それを右揃えで出力

[戻る] [ホームページ]
No.8550

階乗の配列を用いた計算
投稿者---ゆーき(2003/07/21 23:31:01)


こんにちは。学校の課題について質問です。
教授に聞いても自分で調べなさいの一点張りなもので・・・。
1!〜53!の階乗値を配列を使って求めて、それを右揃えで出力せよ、
という課題なのですが、どうしても右揃えで出力できません。
あと、出力部を別関数(void print(...))みたいな形でkaijou関数から
独立させたいのですが、いろいろやってみたもののうまくコンパイルすら
できずに困っています。どうしたらいいのでしょうか?
ご教授おねがいします。

#include<stdio.h>

void set(int process[],int size,int init_value);
void kaijou(int process[],int);

main()
{

  int process[70],k;

  set(process,70,1);

  kaijou(process,53);

}

void set(int process[],int size,int init_value)
{
   int i;

   for(i=1;i < size;i++)
      process[i]=0;
      process[0]=init_value;
}

void kaijou(int process[],int n)
{
   int i,s,a,count,k;

   count=0;  

   for(i=1;i<=n;i++){
      a=0;
      for(s=0;s<=count;s++){
        process[s]=process[s]*i+a;
        a=0;
        if ((process[s]/10000)!=0){
          a = process[s]/10000;
          process[s]=process[s]%10000;    
        }
      }
      if (a!=0){
        process[s]=a;
        count++;      
      }
      
      printf("%d!=%d",i,process[count]);
      
      for(s=count-1;s>=0;s--)
        printf("%04d",process[s]);
      
      printf("\n");
   }
}


No.8556

Re:階乗の配列を用いた計算
投稿者---ともじ(2003/07/22 01:48:08)


こんばんは。

>1!〜53!の階乗値を配列を使って求めて、それを右揃えで出力せよ、
>という課題なのですが、どうしても右揃えで出力できません。

53の階乗の桁数を数値で与えてもよいのなら、最大桁数から0まで
降順にループで回し、countより大きいときにはスペース、等しい
ときには "%4d"、より小さいときには "%04d" で表示すれば
よいように思います。

>あと、出力部を別関数(void print(...))みたいな形でkaijou関数から
>独立させたいのですが、いろいろやってみたもののうまくコンパイルすら
>できずに困っています。

kaijouの呼び出しができているので、こちらもできると思いますが。
コンパイルのできない形でもいいので、UPしてみてください。

それから、これは関数の作りの問題なのですが、1〜53の階乗を一度に
作成する関数をmainから呼ぶのではなく、与えた数値の階乗を作成する
関数をmainで1〜53までループさせて呼ぶ方がいいと思いますが。


No.8557

Re:階乗の配列を用いた計算
投稿者---かずま(2003/07/22 09:22:34)


> 1!〜53!の階乗値を配列を使って求めて、それを右揃えで出力せよ、
> という課題なのですが、どうしても右揃えで出力できません。

こんなやり方もあります。
>       printf("%d!=%d",i,process[count]);

        printf("%d!=%*d", i, 70-4*count, process[count]);


No.8569

Re:階乗の配列を用いた計算
投稿者---ゆーき(2003/07/22 18:37:22)


ともじさん、かずまさんありがとうございます。おかげさまで右揃えは
うまくでいたのですが、やはり出力のところがうまくいきません。
もう混乱してしまって、なにがなにやら分からなくなってしまいました。
ものすごく初歩的なことなのかもしれませんが、お願いします。

#include<stdio.h>

void set(int process[],int size,int init_value);
void print(int process[],int);
void kaijou(int process[],int);

main()
{
	int process[20],k;

	set(process,70,1);
         kaijou(process,53);
     print(process,53);
}

void set(int process[],int size,int init_value)
{
	int i;

	for(i=1;i < size;i++)
		process[i]=0;

	process[0]=init_value;
}

void kaijou(int process[],int n)
{
  省略
}  
void print(int process[],n)
{
	int i,s,count;

	for(i=1;i<=n;i++)
		for(s=0;s<=count;s++){
			if(s==count)
				printf("%d!=%*d",i,70-4*count,process[count]);
			else
				for(s=cocunt-1;s>=0;s--)
					printf("%04d",process[s]);
		}
		printf("\n");
	}
}		


>ともじさん
 >それから、これは関数の作りの問題なのですが、1〜53の階乗を一度に
 >作成する関数をmainから呼ぶのではなく、与えた数値の階乗を作成する
 >関数をmainで1〜53までループさせて呼ぶ方がいいと思いますが
この事について詳しく教えていただけないでしょうか?

No.8573

Re:階乗の配列を用いた計算
投稿者---ともじ(2003/07/22 23:16:44)


こんばんは。

>おかげさまで右揃えはうまくでいたのですが、

お手数ですが、右揃えが上手くできたものを見せてくれますか。

>やはり出力のところがうまくいきません。
void print(int process[], int n)
{
    int i,s,count;

    for(i=1;i<=n;i++) {
        for(s=0;s<=count;s++){
            if(s==count)
                printf("%d!=%*d",i,70-4*count,process[count]);
            else
                for(s=count-1;s>=0;s--)
                    printf("%04d",process[s]);
        }
        printf("\n");
    }
}        
コンパイル自体は、太字部分を直すと消えますが。
右揃えが上手くいったものを拝見してから、アドバイスできればと思います。

>>ともじさん
> >それから、これは関数の作りの問題なのですが、1〜53の階乗を一度に
> >作成する関数をmainから呼ぶのではなく、与えた数値の階乗を作成する
> >関数をmainで1〜53までループさせて呼ぶ方がいいと思いますが
>この事について詳しく教えていただけないでしょうか?

int main(void)
{
    int process[N];        /* 階乗を求める配列 */
    int max;               /* 階乗配列の最大要素数 */
    int count;             /* 求める階乗の要素数 */
    int i;

    /* 53の階乗の要素数を求める */
    max = kaijou(process, 10);
    for (i = 1; i <= 10; i++) {
        /* processにiの階乗を得る */
        count = kaijou(process, i);
        /* iの階乗を右詰めで表示する */
        print(process, i, count, max);
    }
        
    return 0;
}

こんな感じにすると、kaijouで自由に階乗を求めることができるので
いいのではないかと思いました。
課題の場合、関数を使いまわすことまで考えなくてもいいので、
ゆーきさんの方法でかまいませんが、実際に関数を作る場合には
なるべく他でも使えるような関数を作るべきだと思います。
ただ、この方法ではkaijouで毎回1〜iまでの階乗を計算するので
すごく効率がよくありません。作りは臨機応変にということで
お任せします。



No.8579

Re:階乗の配列を用いた計算
投稿者---ゆーき(2003/07/23 01:00:21)


こんばんは。ともじさん、何度もありがとうございます。
右揃えはかずまさんのものを参考にさせていただきました。

#include<stdio.h>

void set(int process[],int size,int init_value);
void kaijou(int process[],int);

main()
{

  int process[70],k;

  set(process,70,1);

  kaijou(process,53);

}

void set(int process[],int size,int init_value)
{
   int i;

   for(i=1;i < size;i++)
      process[i]=0;
      process[0]=init_value;
}

void kaijou(int process[],int n)
{
   int i,s,a,count,k;

   count=0;  

   for(i=1;i<=n;i++){
      a=0;
      for(s=0;s<=count;s++){
        process[s]=process[s]*i+a;
        a=0;
        if ((process[s]/10000)!=0){
          a = process[s]/10000;
          process[s]=process[s]%10000;    
        }
      }
      if (a!=0){
        process[s]=a;
        count++;      
      }
      
      printf("%2.1d!=%*d",i,70-4*count,process[count]);
      
      for(s=count-1;s>=0;s--)
        printf("%04d",process[s]);
      
      printf("\n");
   }
}


を、
#include<stdio.h>

void set(int process[],int size,int init_value);
void kaijou(int process[],int);
void print(int process[],int);

main()
{
	int process[20],k;

	set(process,70,1);

	kaijou(process,53);

	print(process,53);
}

void set(int process[],int size,int init_value)
{
	int i;

	for(i=1;i < size;i++)
		process[i]=0;

	process[0]=init_value;
}

void kaijou(int process[],int n)
{  
	int i,s,a,count,k;

	count=0;  

	for(i=1;i<=n;i++){
    	a=0;
     	for(s=0;s<=count;s++){
      		process[s]=process[s]*i+a;
       		a=0;
        	if((process[s]/10000)!=0){
				a = process[s]/10000;
        		process[s]=process[s]%10000;    
      		}
    	}
    if(a!=0){
    	process[s]=a;
    	count++;      
    }
}

void print(int process[], int n)
{
    int i,s,count;

    for(i=1;i<=n;i++) {
        for(s=0;s<=count;s++){
            if(s==count)
                printf("%d!=%*d",i,70-4*count,process[count]);
            else
                for(s=count-1;s>=0;s--)
                    printf("%04d",process[s]);
        }
        printf("\n");
    }
}        



という風にしてみたのですが、どうしてもprint関数部がコンパイルで
引っかかってしまいます。どうすればいいのでしょうか?
質問ばかりで大変申し訳ないのですが・・・

No.8580

Re:階乗の配列を用いた計算
投稿者---ともじ(2003/07/23 01:24:37)


下の方のプログラムのコンパイルエラーは kaijouの for(i=1;i<=n;i++){
に対する } が足りないから生じるのですが、コンパイルエラーを消しても
mainの中で、
    kaijou(process,53);
    print(process,53);
と階乗算出の関数と表示の関数を一緒に
呼んでいるうちは処理ができません。
ゆーきさんのプログラムの作り方ですと、kaijouの中で、1〜53の階乗
を全て求めているので、kaijouを呼び終わった後で、processに格納
されているのは、53の階乗になるからです。

ですから、今のつくりですと、printを呼ぶのはkaijouの中で現在
printfで配列の中を表示している部分にするしかありません。
その場合、引数にはprocessとcountとiを渡す必要があります。


No.8599

Re:階乗の配列を用いた計算
投稿者---ゆーき(2003/07/23 23:32:32)


いろいろとありがとうございました。
プログラムのほうは結局提出期限の関係で、print関数を
独立させずに作りました。
本当にありがとうございました。