サイトマップ / C言語講座出入り口総目次目次:関数>パスカルの三角形

青い直線

パスカルの三角形

青い直線

[sscanf( )とsprintf( )]←このソース→[16進文字列を10進数に変換]

/* パスカルの三角形をご存じでしょうか。ピタゴラスの三角形とは違います。10行のパスカルの三角形を下記に示します。

                             1
                          1     1
                       1     2     1
                    1     3     3     1
                 1     4     6     4     1
              1     5    10    10     5     1
           1     6    15    20    15     6     1
        1     7    21    35    35    21     7     1
     1     8    28    56    70    56    28     8     1
  1     9    36    84   126   126    84    36     9     1

今回は10行のパスカルの三角形を2次元配列に書き込みます。上記の三角形は今回のプログラムを実行した結果できたものです。

ソースプログラムの説明

三角形の構造を行単位で見ると両端は1です。途中の要素はその要素の上の2つの要素の合計です。

各行の値を保存するには2 次元のint型の配列が自然です。配列の名前をtpas[ ][ ]とします。要素の数は10行10列です。配列の要素と各行および列との関係はtpas[行][列]となります。今回は配列の0行目と0列目の要素は使いません。また、'行' < '列'となっている要素も使いません。

ソースプログラム中に特定の数字(マジックナンバー)を書くのは良くないので、10をMAX_Nとします。

上記の三角形の性質をそのままソースプログラムに変換したものを下記に示します。

    // MAX_N 行のパスカルの三角形の値を計算して tpas[ ][ ] にしまう
    for (i = 1; i <=MAX_N; i++) {
        for (j = 1; j <= MAX_N; j++) {

            if (j == 1)                 // 行の左端は 1
                tpas[i][j] = 1;

            else if (j == i) {          // 行の右端も 1
                tpas[i][j] = 1;
                break;        // 右端まで計算したので内側のループから抜ける
            }

            else              // 行の途中は一つ上の二つの要素の合計
                tpas[i][j] = tpas[i - 1][j - 1] + tpas[i - 1][j];
        }
    }

上記の計算結果の入っているtpas[i][j]を2重のfor ループで表示すると下記のようになってしまいます。正三角形に表示させるには各行にスペースを入れなければなりません。

1
1     1
1     2     1
1     3     3     1
1     4     6     4     1
1     5    10    10     5     1
1     6    15    20    15     6     1
1     7    21    35    35    21     7     1
1     8    28    56    70    56    28     8     1
1     9    36    84   126   126    84    36     9     1

1 行目に必要なスペースの数nは各数字を書式文字列"%3d "でファイルに書き込むとすると、書式文字列は3桁の数字と3つのスペースから成っているので、10行目の真ん中の列の真上に1行目の要素が来るためには、(MAX_N -1) * 3個のスペースが必要です。以下、行が1つ増える度に必要なスペースは3づつ減少していくので、スペースを出力するルーチンは下記のようになります。

    for (i = 1; i <=MAX_N; i++) {
        // スペースの書き込み
        n = (MAX_N - i) * 3;        // n に i 行目に必要なスペースの数が入る
        while (n--)                 // n 個のスペースの書き込み
            putc(' ', fp);
    }

後は、ソースプログラム中のコメントを見て下さい。 */

/* ここからソースプログラム */

#include <stdio.h>

#define MAX_N 10

void main(void);

void main(void)
{
    int i, j;
    int n;
    int tpas[MAX_N + 1][MAX_N + 1];

    printf("                 10行のパスカルの三角形\n\n\n");

    /* MAX_N 行のパスカルの三角形の値を計算して tpas[ ][ ] にしまう */
    for (i = 1; i <=MAX_N; i++) {
        for (j = 1; j <= MAX_N; j++) {

            if (j == 1)           /* 行の左端は 1 */
                tpas[i][j] = 1;
			
            else if (j == i) {    /* 行の右端も 1 */
                tpas[i][j] = 1;
                break;            /* 右端まで計算したので内側のループから抜ける */
            }

            else                  /* 行の途中は一つ上の二つの要素の合計 */
                tpas[i][j] = tpas[i - 1][j - 1] + tpas[i - 1][j];
        }
    }

    /* MAX_N 行のパスカルの三角形を表示 */
    for (i = 1; i <=MAX_N; i++) {
        /* スペースの書き込み */
        n = (MAX_N - i) * 3;        /* n に i 行目に必要なスペースの数が入る */
        while (n--)		/* n 個のスペースの書き込み */
        putchar(' ');
                /* 数字の書き込み */
        for (j = 1; j <= MAX_N; j++) {
            if (i == j) {        /* 行の右端は数字のみ書き込む */
                printf("%3d", tpas[i][j]);
                break;    /* 行の右端に達したので内側のループから抜ける */
            }
            else    /* 行の途中は数字とスペースを書き込む */
                printf("%3d   ", tpas[i][j]);
        }
        printf("\n");        /* 1 行書き込んだら改行 */
    }

}

/* ここまでソースプログラム */

/* 三角形の各行のスペースを無視して、各行を一つの数字に見立てると、以下の数列が得られます。

    1, 11, 121, 1331, 14641, 15101051, 1615201561,
    172135352171, - - - - -

これらの数字は回文のように前から読んでも後ろから読んでも同じです。実は、11 の n-1 乗になっています。

パスカルの三角形にはこの他にも、興味深い数列を複数含んでいます。三角形の右上がりの方向の斜めの線上の数字を合計すると、フィボナッチ数列になります。

    1, 1, 2, 3, 5, 8, 13, - - -

*/

[sscanf( )とsprintf( )]←このソース→[16進文字列を10進数に変換]

青い直線

/* (C) 2000- YFプロ. All Rights Reserved. */    提供:C言語講座−それ自体コンパイルできる教材を使った講座です−

青い直線

サイトマップ / C言語講座出入り口総目次目次:関数>パスカルの三角形