問題提起その 1 一文字ずつ文字(数字)を読み込み、それぞれの文字が何回入力されたかを数えて出力するプログラム。

Slides:



Advertisements
Similar presentations
アルゴリズムと データ構造 第 3 回 基本的なデータ構造(2) : 配列 1. 前回の復習 アルゴリズムの計算量 最悪(最大)計算量 計算量の漸近的評価 (オーダ)  多項式時間アルゴリズム( polynomial time algorithm )  指数時間アルゴリズム( exponential.
Advertisements

1 繰り返し処理 while 文 と do 文 所定回反復(特定回数の繰り返し)には for 文を用いた while( 式 ) 文 式が真であるかぎり、文を繰り返し実行する 繰り返す回数が不定の場合に用いる 繰り返し回数が明示的に決まらない場合には while 文、 do 文を用いる ある手順を、例えば.
1 第5回 配列. 2 今回の目標 マクロ定義の効果を理解する。 1次元配列を理解する。 2次元配列を理解する。 ☆2 × 2の行列の行列式を求めるプログラ ムを作成する.
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
初年次セミナー 第8回 データの入力.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第4回 配列(2) 情報・知能工学系 山本一公
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
ファーストイヤー・セミナーⅡ 第8回 データの入力.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
プログラミング基礎I(再) 山元進.
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
C言語 配列 2016年 吉田研究室.
問題 1 フィボナッチ数列 xn は次で定義される。
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
アルゴリズムとデータ構造 2011年6月13日
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
情報理論2 第6回 小林 学 湘南工科大学 2011年11月15日 〒 神奈川県藤沢市辻堂西海岸1-1-25
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
データ構造とアルゴリズム論 第2章 配列(構造)を使った処理
精密工学科プログラミング基礎 第9回資料 (12/11 実施)
情報処理Ⅱ 2007年11月5日(月).
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
プログラミング論 II 2008年10月30日 文字列
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラムの制御構造 配列・繰り返し.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
精密工学科プログラミング基礎Ⅱ 第4回資料 今回の授業で習得してほしいこと: 文字列の扱い ファイル入出力の方法 コマンドライン引数の使い方
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
疑似乱数, モンテカルロ法によるシミュレーション
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
アルゴリズムとプログラミング (Algorithms and Programming)
ポインタとポインタを用いた関数定義.
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング論 ポインタ
地域情報学 C言語プログラミング 第4回 while文、do~while文、switch文、 2次元配列、ポインタ 2017年11月10日
精密工学科プログラミング基礎 第7回資料 (11/27実施)
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
オブジェクト指向言語論 第二回 知能情報学部 新田直也.
プログラミング 4 文字列.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
情報処理Ⅱ 2006年11月8日(金).
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
情報処理Ⅱ 2005年11月25日(金).
プログラミング入門2 第5回 配列 変数宣言、初期化について
第4回 配列.
知能情報工学演習I 第9回(後半第3回) 課題の回答
第5回 配列.
知能情報工学演習I 第10回( C言語第4回) 課題の回答
プログラミング演習I 補講用課題
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

問題提起その 1 一文字ずつ文字(数字)を読み込み、それぞれの文字が何回入力されたかを数えて出力するプログラム。 int code, count_0=0, count_1=0, count_2=0, count_3=0, ...., count_9=0; while( (code=getchar()) != EOF ){ switch(code){ case ‘0’: count_0++; break; case ‘1’: count_1++; break; .... case ‘9’: count_9++; break; } printf(“0 は %d 個入力された\n”,count_0); printf(“1 は %d 個入力された\n”,count_1); 同じ型の変数を 10 個用意して プログラムするのは大変!

問題提起その 2 20 個の整数値(もしくは実数値)を読み込んで、昇順に並び替えたい。 考え方 20 個の変数を宣言して数値を格納(記憶)する。 変数の並び替え(ソート) int a0, a1, a2, ..., a19; scanf("%d", &a0); scanf("%d", &a1); .... 20 個の値の読み込み 変数を 20 個宣言するのは大変である。また、記憶する数値の個数がさらに増えると値を格納する変数を用意するだけでも大変。

配列 int a[10]; a[0] a[1] ... a[9] int a; a 同じ型のデータの集まりを配列という。 10 個の要素からなる 整数型の配列 a を宣言 int a[10]; 配列名の後の [ ] の中に添え字が入る。添え字は整数型。 配列の要素は添え字で指定する。 a[0] a[1] ... a[9] 添え字は 0 から始まる。 i 番目の要素は a[i] で表す( i = 0, 1, 2, ... , 9)。 同じ型で構成される複数のデータをまとめたものが配列。 これまで扱ってきた変数: 整数型の変数 a を宣言 int a; a

配列 2 int a[10]; a[0] a[1] ... a[9] は、10 個の整数型の要素を持つ配列を宣言 10 個の要素を持つ配列の場合、許される添え字は 0 から 9 までの 10 個である。 a[0] = 3; a[3] = 7; 0 番目の要素に 3 を代入。 3 番目の要素に 7 を代入。 上の配列 a の場合、a[10] や a[11] という添え字は範囲外参照となり、おかしな結果を招く(コンパイルエラーにならないので注意が必要)。 当然 a[-1] という参照も範囲外参照。 a[10] = -4; a[10] は存在しないので不可!(コンパイルはできるので注意)

配列 3 配列の要素数は、コンパイル時に確定していなければならない。 int size, a[size], i; scanf("%d", &size); /* 配列の初期化 */ for(i=0; i<size; i++) a[i] = 0; 配列要素数がコンパイル時に確定していないので不可(コンパイルエラー) 配列サイズ(要素数)は静的。動的にはとれない。 コンパイル時に、コンパイラは配列要素を格納するメモリ領域を確保するため。

配列 4 配列を宣言しただけでは、配列要素の中身は不確定(変数と同じ)。 int a[10], i; /* 配列の初期化 */ for(i=0; i<10; i++) a[i] = 0; 要素を指定した配列は、今まで通りの 変数と同じ。a[i] は i 番目の要素。 もしくは、下のように、宣言と同時に初期化も可能。 int a[10] = {1,2,3,4,5,6,7,8,9,10}; 配列は、int 型以外にも float, double, char 等の型について使用できる。 double x[100], y[100]; char code[256];

例 1 文字定数 '0' ~ '9' の出現回数を数える。 int code, count[10], i; for(i=0; i<10; i++) /* 配列要素の初期化 */ count[i]=0; while( (code=getchar()) != EOF ){ switch(code){ case ‘0’: count[0]++; break; case ‘1’: count[1]++; break; .... case ‘9’: count[9]++; break; } for(i=0; i<10; i++) printf(“%c は %d 個入力された\n”, i+’0’, count[i]); count[0] は ‘0’ の入力回数を数える count[1] は ‘1’ の入力回数を数える ...

例 2 switch 文を使わない例 int code, count[10], i; for(i=0; i<10; i++) /* 配列要素の初期化 */ count[i]=0; while( (code=getchar()) != EOF ){ if( code >= ‘0’ && code <= ‘9’ ) count[ code-’0’ ]++; } for(i=0; i<10; i++) printf(“%c は %d 個入力された\n”, i+’0’, count[i]); 添え字が code-’0’ になっていることに注意。if 文の条件判断で、読み込んだ文字が 0 から 9 の間にあることを保証しておかないと範囲外参照になる。

例 3 10 個の数値を配列へ格納(記憶)する。 int i, data[10]; for(i=0; i<10; i++) /* 配列へデータを読み込む */ scanf("%d", &data[i]); for(i=0; i<10; i++) printf(“%d 番目のデータは %d\n”, i, data[i]); /* 配列 data に格納された値を並び替える(ソート)*/ 配列を使うと、複数のデータの取り扱い(入出力など)が易しくなる。

多次元配列 a[0] a[1] a[2] a[3] a[4] b[0][0] b[0][1] b[0][2] b[1][0] b[1][1] int a[5]; 1 次元配列 a[0] a[1] a[2] a[3] a[4] int b[4][3]; 2 次元配列 12 個の要素からなる 2 次元配列 b[0][0] b[0][1] b[0][2] 4 行 3 列の行列に相当 b[1][0] b[1][1] b[1][2] b[2][0] b[2][1] b[2][2] b[3][0] b[3][1] b[3][2] 一般に、b[M][N] は M 行 N 列の行列に相当 b[i][j] は ( i, j ) 成分 2 つの添え字で要素を指定。添え字の範囲に注意! 0 ≤ i < 4, 0 ≤ j < 3

多次元配列の初期化 配列の宣言と同時に配列要素を初期化できる。 int a[2][3] = {{1,2,3},{2,3,4}}; int b[2][3] = {{0,0,0},{-1,-2,3}}; int c[2][3], i, j; for(i=0; i<2; i++) for(j=0; j<3; j++) c[i][j] = a[i][j] + b[i][j]; 初期化数値が配列サイズを越えるとコンパイルエラー。 足りない分は int 0 で初期化。 double x[10][10][10]; 10*10*10=1000 個の要素からなる 3 次元配列

メモリ上の配列および変数の配置 配列の添え字の範囲はプログラマの責任。配列の範囲外参照はおかしな動作・結果を招く。 int a, b; a ... a[9] 正しい添え字の範囲は 0 から 9 まで! b ここで、a[10] = 1 の様な範囲外参照および代入をすると、隣に確保された 変数 b の領域を侵害して変数 b の値がおかしくなってしまう。

オブジェクト sizeof 式 または sizeof( 型名 ) 変数や配列など、計算機のメモリ上に格納されるものをオブジェクト object と呼ぶ。オブジェクトが占めるメモリ領域をオブジェクトサイズという。 オブジェクトサイズを知るには sizeof 演算子を用いる。 sizeof 式 または sizeof( 型名 ) sizeof 演算子は、式もしくは型名の変数に割り当てられるオブジェクトサイズを返す。単位はバイト。 int a, b[5]; double x, y[5]; printf("sizeof a=%d, b=%d\n, sizeof(int), sizeof b); printf("sizeof x=%d, y=%d\n, sizeof(double), sizeof y);

sizeof( int ) sizeof( double ) sizeof( char ) a x 一般的な型のオブジェクトサイズ(処理系により異なる場合がある) sizeof( int ) 4 バイト sizeof( double ) 8 バイト sizeof( char ) 1 バイト int a, b[5]; double x, y[5]; 左のように宣言された変数・配列は下図のメモリ領域を占める。具体的な格納場所(アドレス)は処理系に依存。 オブジェクトの格納場所はアドレス演算子 & を用いて知ることができる。 4 byte 20 byte a b printf("%x\n", &a); printf("%x\n", &b[0]); printf("%x\n", y); &a &b[0] 8 byte 40 byte x y 変換指定 %x :16 進数表示 &x &y[2]

配列のアドレス double x[]={1.0, 2.0, 3.1415}; 1.0 2.0 3.1415 配列を宣言と同時に初期化。要素数を省いて宣言すると、初期値の個数(この場合 3)が要素数となる。 1.0 2.0 3.1415 x[0] x[1] x[2] &x[0] = x 配列名は、その配列が格納されているアドレスを表す。 (0 番目の要素のアドレスに等しい。配列名は配列へのポインタ) printf("Addres of score[0] is %x\n", &x[0]); printf("Addres of score is %x\n", x); & は不要!

問題 1 キーボードから 10 人の成績(100 点満点の整数値)を配列に読み込み、1) 平均点、2) 分散、及び 3) 標準偏差を計算・表示するプログラム % ./a.out 学籍 No. 0 の成績:80 学籍 No. 1 の成績:70 学籍 No. 2 の成績:95 学籍 No. 3 の成績:90 ... 学籍 No. 8 の成績:90 学籍 No. 9 の成績:40 平均点は 85.5 点です。 分散は 246.25 です。 標準偏差は 15.69 点です。 % データ {n1, n2, n3, n4, n5, ..., nk} の 平均は 分散は 標準偏差は

問題 2 キーボードからアルファベットを 1 文字ずつ読み込み、入力したアルファベットの数を数えるプログラム。入力の中断は Ctrl-D とする。数字や記号は無視する。 ただし、大文字と小文字の区別はしない。 % ./a.out アルファベットを入力(Ctrl-D で終了) We had the world cup last year. [Enter] [Crtl-D] a は 3 文字。 b は 0 文字。 c は 1 文字。 ... z は 0 文字。 % 26 個のアルファベットの出現回数を数える配列を用いる。 int count[26];

問題 3 3 行 3 列の行列を入力し、その和を計算するプログラム。 n × n 行列 A = (aij), B = (bij) % ./a.out 行列 A の成分を入力せよ。 a[0][0] = 3 a[0][1] = 4 a[0][2] = 5 a[1][0] = -3 a[1][1] = 0 ... 行列 B の成分を入力せよ。 b[0][0] = 1 b[0][1] = -6 行列 A + B は 4 -2 6 -2 2 4 1 0 3 n × n 行列 A = (aij), B = (bij) について、和 C = A+B の (i, j) 成分は   cij = aij + bij

問題 4 成績のデータから、各人の合計点および全体の平均点を計算するプログラムを作れ。 平均点は、少数以下を四捨五入すること。 情報 数学 英語 85 70 77 68 75 63 55 80 60 91 47 53 成績は初期値として与えておく。 int seiseki[6][4] = {85,70,77,0}, {68,75,63,0},{55,80,60,0}, {75,63,91,0},{47,53,70,0}, {0,0,0,0}}; 合計と平均点を格納する場所を 用意しておく。初期値として0。 % ./a.out 情報  数学  英語  合計 85 70 77 232 68 75 63 206 55 80 60 195 75 63 91 229 47 53 70 170 66 68 72 206

エラトステネスのふるい N 以下の素数を求めるアルゴリズムとして、エラトステネスのふるいがある。 アルゴリズム ◎ 2 から N までの数を並べる。全ての数に印(例えば int 1 )を割り振っておく。 ◎ 2 の倍数(2 自身は除く)に印(例えば int 0)を割り振る。 ◎ 印 1 が着いている最小の数は 3 である。3 の倍数(3 自身は除く)に印(0)を割り振る。 ◎ 印 1 が着いている最小の数は 5 である。5 の倍数(5 自身は除く)に印(0)を割り振る。 ◎ 印 1 が着いている最小の数は 7 である。7 の倍数(7 自身は除く)に印(0)を割り振る。 ... ◎ 以上の操作を繰り返す。最後に印 1 が着いている数が素数である。 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... 全ての数に印を付ける 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... 2 を除く偶数(2の倍数)を候補から除く 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ... 奇数かつ 3 の倍数は素数ではないので 3 の倍数を除く

問題 5 エラトステネスのふるいを用いて、1000 以下の素数を全て表示せよ。 ただし表示形式として、1 行に 10 個ずつ表示されるようにすること。 % ./a.out 2 3 5 7 11 13 17 19 23 29 31 37 ... 947 953 967 ... 983 991 997 % ヒント int a[1001] を宣言 素数の候補に印 int 1 を付ける。 a[0] = 0, a[1] = 0, a[2] = 1, a[3] = 1, a[4] = 1, ... 印 1 が着いている最も小さな添え字は 2。 2 の倍数は素数ではないので、4, 6, 8, ... に 印 0 をつける。  a[4] = 0, a[6] = 0, a[8] = 0, a[10] = 0, ... 印 1 が付いている、値 start 以降で最も小さな添え字の探索方法 for(i=4; i < 1000; i += 2) a[i] = 0; i = start; while( a[i]==0 ) i++; 印 1 が着いている最も小さな添え字は 3。 3 の倍数は素数ではないので、6, 9, 12, ... に 印 0 をつける。  a[6] = 0, a[9] = 0, a[12] = 0, a[15] = 0, ... このとき、a[i]が全て0であれば繰り返しが終了しない。最後には0以外が入っていることが必要(番兵センチネル)