第10回[平成15年6月26日(木)]:PN03-10.ppt 配列(2) 今日の内容 1 2 3 4 5 6 素数を求める(教科書の例):復習 素数を求める(エラトステネスの方法) 代入式とコンマ演算子 二次元配列とは 二次元配列の入力・出力と計算 二次元配列を用いた計算 復習 素数(その1:p.104-111) unsigned は符号なし List 5-15 int i, no; 第3回目pptファイルを参照 unsigned long cnt=0; for ( no=2; no<=1000; no++) { for ( i=2; i<no; i++) { cnt++; if ( no % i == 0 ) break; } if (no==i) printf("%d\n",no); } printf("乗除回数: %d\n",cnt); 復習 /* 偶数をはじめから除く */ ・・・・ no = 2; /* 奇数のみを調べる */ printf("%d\n",no++); no は 3 for ( no=2; no<=1000; no+=2 no++ ) { for ( i=2; i++ ) { i=3 i<no; i+=2 cnt++; if ( no % i == 0 ) break; } if (no==i) printf("%d\n",no); } printf("乗除回数: %d\n",cnt); List 5-16,-17 int prime[500]; int ptr=0; 復習 ・・・・ /* 既得素数を配列に保存 */ prime[ptr++] = 2; prime[0]←2 prime[ptr++] = 3; prime[1]←3 for ( no=5; no<=1000; no+=2) { for ( i=1; i<ptr; i++) { cnt++; if(no % prime[i] == 0) break; } if (ptr==i) prime[ptr++]=no; } List 5-18 prime[ptr++]=2; prime[ptr++]=3; for ( no=5; no<=1000; no+=2) { int flag = 0; for ( i=1; cnt++,prime[i]*prime[i]<=no; i++) { cnt++; if(no % prime[i] == 0) { flag = 1; break; } } if ( !flag ) prime[ptr++]=no; } List 5-19 コンマ演算子(p.110) op1,op2,・・,opn →左から順に評価 (op1、op2、..、opnの順に評価す る) → 式全体としてはopnの評価値となる b = 5; a a = ( a=3, b+=a, c=b*5); b 5 c for ( i=10, j=0; i>j; i--, j++) (注)a= a=3, b+=a, c=b*5; 違う結果! 代入式(p.98) • 代入式→変数へ値を代入する式(p.23) int k; double a=1.1, b=2.2; k = a + b; k = a + b k = a=k=b=3.14 代入式; → 式文 k a b 前回の課題 • 次の式の値、各変数の値を求めよ。ただ し、変数は全て整数型とする。 a=5; a+2; a=b=a+1; a=5; a=b=a+1.5; a=b=5; c=( a+2, b+3); a=2; if( a=1 ) b=a; else b=a; a=1; if( a==1, a==2) b=1; else b=0; a=2; if( a==1, a==2) b=1; else b=0; a=1; if( a++, (a==2)-(a=1)) b=1; else b=0; 提出用紙に授業への意見・感想・提案も書いて下さい 素数(その2) • エラトステネスの篩(ふるい)のアルゴリズ ムを用いて、1000以下の素数をすべて求 め、1行に10個ずつ出力せよ。 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17… 2の倍数を除く 2 3 - 5 - 7 - 9 - 11 - 13 - 15 - 17 - … 3の倍数を除く → 9(=3*3) から始める 2 3 - 5 - 7 - = - 11 - 13 - = - 17 - 19… 5の倍数を除く → 25(=5*5)から始める 2 3 - 5 - 7 - - - 11 - 13 - - - 17 - 19… #include <stdio.h> #define MAXN 1000 /* 上限値 */ int main (void) { int a[1001],i,k,cnt; /*配列の初期化,a[0],a[1]は使わない 配列の全要素を true(1) とする */ for (i=2; i<=MAXN; i++) a[i]=1; /* 素数でない値を添字に持つ配列要素 */ /* を false(0) にしていく */ /* (篩にかけていく) */ /* 結果の出力へ続く /* 篩の部分 */ 偶数もす for (i=2; i<=MAXN; i++) べて調べ if ( a[i] ) ている for (j=2*i; j<=MAXN; j=j+i) a[j] = for文に無駄 → 3以上の偶数は調べ 0; る必要がない ・偶数は最初に除くようにする 演習 ・while文 又は do-while文 で書き替えよう /* 4以上の偶数の要素はすべて false */ for ( ; i<=MAXN; ) a[i] = 0; /* 3以上の奇数についてチェックする */ i = 3; while ( i <= MAXN ) { if ( a[i] ) { ; while ( j <= MAXN ) { ; ; } } ; } /* これより、結果出力 */ /* a[i] が true(1) の要素を出力 */ /* 1行に10個ずつ出力 */ cnt = 0; for ( i=2; i<=MAXN; i++) if ( ) { printf("%4d ",i); ; if ( ) printf("\n"); } } 演習 • エラトステネスの篩のプログラムの以下 の部分を for文 を使って書き替えよ i = 3; while ( i <= MAXN ) if ( a[i] ) { j = i*i; while ( j <= MAXN ) { a[j] = 0; j = j + i; } } i = i + 2; } 二次元配列とは • 要素を二つの整数の組で指定する配列 int d[10]; int a[6][10]; 第2添字・列 integer [0][1]・・・[8][9] 第 d[0] 1 [0 d[1] ・・・ 添 ] ・ 字 [1 ・ ・ a[4][1 d[2] ・ ・ ・ ・ : ・ ] ] : 行 : ・・・ d[9] ・ 宣言により、連続した int a[6][10]; a[0][0] 記憶場所が確保される 第 1 添 字 ・ 行 第2添字・列 [0][1]・・・[8][9] [0 ・・・ ] ・ ・ ・ [1 ・ ・ ・a[4][1 ・ ] ] ・・・ : ・ a[0][1] : a[0][9] a[1][0] a[1][1] : a[1][9] : a[5][0] a[5][1] : a[5][9] 初 期 値 も こ の 順 に 記 録 さ れ る 二次元配列の初期化 a [0][1] [0 ] [1 ] a[0][0]=1; [2 a[1][0]=3; ] a[2][0]=5; int a[3][2]={ {1,2}, {3,4}, {5,6}, }; a[0][1]=2; a[1][1]=4; a[2][1]=6; int a[3][2]={1,2,3,4,5,6}; 演習(二次元配列の初期化) int d[4][3]= {1,2,3,4,5,6,7,8,9,10,11,12}; のとき、次の要素の値はいくつか? d[0][0] → d[3][2] → d[2][2] → d[1][1] → d[0][3] → d [0][1][2] [0 ] [1 ] [2 ] 二次元配列への入力 a [0][1] [0 int a[3][2]; ] 添字を指定して、変数 [1 のように入力する ] scanf("%d",&a[0][0]); [2 scanf("%d %d",&a[1][0],&a[2][0]); ] i=1; scanf("%d %d %d", &a[0][i],&a[1][i],&a[2][i]); for (i=0; i<3; i++) scanf("%d %d",&a[i][0],&a[i][1]); 二次元配列への入力 for文を利用して添字を指定する int a[10][2]; for ( i=0; i<10; i++) scanf("%d %d", &a[i][0], &a[i][1]); int a[10][5]; for ( i=0; i<10; i++) for ( j=0; j<5; j++) scanf("%d", &a[i][j]); 演習(二次元配列への入力) 10人分の学籍番号、英語、数学の点数を順 番に配列に入力する以下の部分を完成せよ。 for文を利用して添字を指定する int d[ ][ ], i, j; for (i= ; i< ; i++) for (j= ; j< ; j++) scanf("%d",&d ); 続いて、入力、出力の全体を書いてみよう。 二次元配列への入力 int a[10][3], i; printf("番号、英語、数学の入力\n"); for (i=0; i<10; i++) scanf("%d %d %d", &a[i][0],&a[i][1],&a[i][2]"); printf("入力データは"); for (i=0; i<10; i++) printf("%-8d %6d %6d\n", a[i][0],a[i][1],a[i][2]); 二次元配列を用いた計算 各学生の合計得点の計算 a[0][3] = a[0][1]+a[0][2]; a[1][3] = a[1][1]+a[1][2]; : for (i=0;i<10;i++) 番 英 数 合 a[i][3] 号 語 学 計 = a [0][1][2][3] [0] [1] [2] : : [8] [9] [10] 二次元配列を用いた計算 a [0][1][2][3] [0] [1] [2] : : [8] [9] [10] 各科目の平均点の計算 j=1; //英語について a[10][j] = 0; for (i=0;i<10;i++) a[10][j] =a[10][j]+a[i][j]; a[10][j] 計科 番 英 数 の 目 =a[10][j]/10; 号 語 学 平 と j=2; //数学について 均合 二次元配列を用いた計算 int a[11][4], i; // 入力処理 for (i=0; i<10; i++) a[i][3]=a[i][1]+a[i][2]; for (j=1; j<=3; j++) { a[10][j]=0; for (i=0; i<10; i++) a[10][j]=a[10][j]+a[i][j]; a[10][j]=a[10][j]/10; } //出力処理 演習(二次元配列を用いた計 算) 前の頁の例で、入力された各学生の番号と各得点 と合計得点、各科目の平均得点・合計の平均得点 を順に出力するプログラムの部分を完成せよ。 printf(" 番号 英語 数学 合計 \n"); for( i=0; i<10; i++) printf("%d, %d, %d, %d\n", a[ ][ ],a[ ][ ],a[ ][ ],a[ ][ ]); printf("平均得点:") printf("数学=%d,英語=%d,合計=%d\n", a[ ][ ],a[ ][ ],a[ ][ ]); 提出用紙に授業への意見・感想・提案も書いて下さい P入門(第10回)は 終了です。 次回(第11回)は 7月3日 続いて、P演習に入ります。 では、しばらく休憩します。
© Copyright 2024 ExpyDoc