物理情報処理基礎実習II 第11回

http://www.phys.ynu.ac.jp/labs/cosmic/shibata/jisshu/
物理情報処理基礎実習II
第11回
文字と配列
~整数・実数配列・計算例~
柴田 [email protected]
(原 [email protected])
石川 [email protected]
§課題9-解答例(大文字小文字変換)
1. #include <stdio.h>
2. main()
3. {
4.
int c;
5.
while((c=getchar())!=EOF){
6.
if(c>64&&c<91){
7.
c=c+32;
8.
}else if(c>96&&c<123){
9.
c=c-32;
10.
}
11.
printf("%c",c);
12.
}
13. }
※^Dで1文字入力終了
※大文字のとき
※小文字に変換(c+=32)
※小文字のとき
※大文字に変換(c-=32)
§課題10のフローチャート(例)
sumx=0.
xmax=-100.
xmin=100.
n
i=0
No
output
i<n ?
Yes
x
sumx=sumx+x
exit
x<xmin?
No
x>xmax?
No
i=i+1
Y
xmin=x
Y xmax=x
§整数・実数配列
配列の変数型
char型配列は、1バイト変数の配列。
整数(4バイト)や
倍精度実数(8バイト)の配列も使える。
宣言方法
int 変数名[配列要素数] = {初期値並び};
double 変数名[配列要素数] = {初期値並び};
配列の必要性
多くの変数を扱う時、プログラムが簡潔に。
ソート(並べ替え)、ベクトル・行列演算、
多項式・数列・級数演算、データ処理などなど。
ex.)
§例 -I- ソート(sort)
 数字の昇順に並べる
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#define N 10
#include <stdio.h>
main()
{
int x[]={4,2,5,3,6,9,0,8,1,7}; ※10個の整数を定義
int i,k,work;
※work は一時記憶用の変数として使用
for( i=0 ; i<N-1 ; i++){
16. for( i=0 ; i<N ; i++){
for( k=i+1 ; k<N ; k++){
17.
printf("%d",x[i]);
if( x[k]<x[i] ){
18.
}
work = x[i];
19.
putchar('\n');
x[i] = x[k];
20. }
x[k] = work;
}

実行結果
}
0123456789
}
§並べ替えのアルゴリズム
配列要素 : x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]
各要素の値: 4 2
5 3
6
9 0
8
1
7
ループ変数は i =0~8, k=(i+1)~9 という値をとっている。
i=0のときの処理:
x[0]=4 より小さい値がx[k] (k=1~9)の中にあればx[0]とx[k]を入れ替え
る。
配列要素 : x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]
各要素の値: 0 4
5 3
6
9 2
8
1
7
これでx[0]は最も小さい値になった。
i=1のときの処理:
x[1]=4より小さい値がx[k] (k=2~9)の中にあればx[1]とx[k]を入れ替える。
配列要素 : x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]
各要素の値: 0 1
5 4
6
9 3
8
2
7
これでx[1]は2番目に小さい値になった。
同様に i=8 まで繰り返す。
配列要素 : x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7] x[8] x[9]
各要素の値: 0 1
2 3
4
5 6
7
8
9
x[9]はx[8]より大きな値になっているからi=9に対する処理は不要。
§例 -II- ベクトル演算
 ベクトルの内積計算 ( A・B=Σai bi , i=0~2)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
#include <stdio.h>
main()
{
double a[3]={1.0,2.0,3.0},b[3]={-1.0,1.0,-2.0},x;
int i;
x=0.0; ※求める内積をxとする。
for(i=0;i<3;i++){
printf("a[%d]=%9.3lf b[%d]=%9.3lf\n",i,a[i],i,b[i]);
x=x+a[i]*b[i];
}
printf(“(A,B)=%9.3lf\n”,x);
 実行結果
}
a[0]=
a[1]=
a[2]=
(A,B)=
1.000
2.000
3.000
-5.000
b[0]=
b[1]=
b[2]=
-1.000
1.000
-2.000
§例 -III- n次多項式 -I( Polynomial)
 y=a0+a1x+a2x2+…+anxn ※例1
=a0+x(a1+x(a2+x(…x(an-1+anx)…))) ※例2
 例1
1.
2.
3.
4.
5.
6.
7.
8.
#include <stdio.h>
#include <math.h>
#define N 3 ※次数
main()
{
double a[N+1]={1.0,3.0,3.0,1.0},x,y;
int i;
printf("x = ");
9.
scanf("%lf",&x);
10.
y=0.0;
11.
for(i=0;i<N+1;i++){
12.
y=y+a[i]*pow(x,i);
13.
}
14.
printf("y = %lf\n",y);
15. }
§例 -IV- n次多項式 -II y=a0+a1x+a2x2+…+anxn ※例1
=a0+x(a1+x(a2+x(…x(an-1+anx)…))) ※例2
 例2
1.
2.
3.
4.
5.
6.
7.
8.
#include <stdio.h>
#include <math.h>
#define N 3 ※次数
main()
{
double a[N+1]={1.0,3.0,3.0,1.0},x,y;
int i;
printf("x = ");
9.
10.
11.
12.
13.
14.
15. }
scanf("%lf",&x);
y=a[N-1]+a[N]*x;
for(i=N-1;i>0;i--){
y=a[i-1]+x*y;
}
printf("y = %lf\n",y);
§課題11 データ処理
[a] ftp serverの ftp.phys.ynu.ac.jp から次のファイル
pub/jisshu/primer/seiseki.d
をダウンロードせよ。このデータには30人分の成績データが
入っており各行のデータ形式は
学籍番号(7桁のゼロ詰整数) (1桁空白) 点数(3桁整数)
となっている。点数の降順(高いもの低いものの順)に並べ替
えて表示せよ。ファイルからのデータ入力については次のペー
ジ( §リダイレクト)を参考にせよ。7桁整数をゼロ詰で出力す
る書式は“%07d”である。
[b] exp(x)の値と、この関数をx=0の周りでテーラー展開し6次
の多項式近似したときの値とをx=[0,1]の範囲で0.05きざみに小
数点以下10桁まで示せ。出力形式は次のようなものである。
x
exp(x)
多項式の値 (改行)
§出力例
x
exp(x)
0.00 1.0000000000
0.05 1.0512710964
0.10 1.1051709181
0.15 1.1618342427
0.20 1.2214027582
....................................
0.90 2.4596031112
0.95 2.5857096593
1.00 2.7182818285
polynomial
1.0000000000
1.0512710964
1.1051709181
1.1618342424
1.2214027556
2.4594963625
2.5855527292
2.7180555556
§リダイレクト
 データの読み込みには、
リダイレクト(redirect)の方法を使用出来る。
 リダイレクトとは、入出力装置を変更することを意味する。
 この場合、プログラムは標準入力を想定して作ればよい。
すなわちキーボード入力を想定して、
scanf などの関数で入力を行うように書く。
 標準入力をプログラムにリダイレクトする方法
プログラム名 < ファイル名
ex.)
aplsrvky01% ./kadai11a < seiseki.d
 これによりファイル内に書かれているデータが、
あたかもキーボード入力されたようにプログラムに渡される。
 この方法を用いれば、大量のデータ入力が可能となるが、
キーボード入力を同時に必要とするような処理はできないことに
注意。
 cf. 標準出力をファイルにリダイレクトするには > 記号を使う。