プログラミング入門2003

第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演習に入ります。
では、しばらく休憩します。