プログラミング基礎I(再)

山元進
最高点 94 点
 最低点 0 点
 多くの人は、もうすこし頑張る必要がある
 基本的に、プログラミングの基礎を学びとった
者に単位が与えられる
 再履修クラスだからと言って採点基準をあまく
する理由は何もない

猿まねは、所詮猿まねでしかない
 サンプルプログラムの動作を理解し、(前提1)
 望みの動作をするよう変更できなければ、(2)
 単位は取れない
(結論)


カーゴ・カルト ・プログラミング(cargo cult programming)
意味を考えないでただ形だけ真似(コピー&ペース
ト)するプログラミングスタイル
 問7 (特に(1),(3)) などが分からない人の書いたプロ
グラムは、端的にいうと役に立たない

問1 基本的に、講義で全く話題に上らなかったこと
が出るはずがない
選択肢
 仮想マシンを起動して中間コードを実行する。
 中間コードをアセンブルする。
 (1)で答えたファイルに[プログラム]を書き込む。
 ソースコードをリンクする。
 java コンパイラに[プログラム]を作らせる。
 java コンパイラに中間コードを生成させる。
 java コマンドを起動してソースコードを読み込む。
import java.io.*;
class Ex2
{
public static void main(String args[])
throws IOException
{
System.out.println("整数を3つ入力。");
BufferedReader br = 【空欄】 BufferedReader(
【空欄】 InputStreamReader(System.in));
// 基本型でない変数が出てきたら、最初に new しないとデータを記録できない
// ここから
String str1=br.readLine();
String str2=br.readLine();
String str3=br.readLine();
int sum=0;
sum += Integer.parseInt(str1);
sum += Integer.parseInt(str2);
sum += Integer.parseInt(str3);
// ここまで
System.out.println("合計は"+sum+"です。");
}
}
元のコードを見れば、3回数字を読み込んで、sum に足しこんでいる。
[代替コード]
int 【空欄A】 = 0;
for(int i=0; i<3; 【空欄B】){
sum += Integer.parseInt(br.【空欄C】());
}
class Ex3
{
public static void main(String args[])
{
for(int i=0; i<10; i++){
System.out.print((i%3>0)?'T':'F');
}
}
i は 0 で始まって for の直後の { } の中身を実行するたびに 1 ずつ増える。
i == 10 になったら for 文を抜ける。 (i==10 のときは、{ } のなか実行せず)
{ } のなかみ
画面に T, F のどちらかを出力
(i が 3 で割ったあまりが 0 より大きければ T, そうでなければ F )
for(int i=0; i<10; i++){
【空欄A】
【空欄B】
【空欄C】
【空欄D】
}
}
[選択肢]
while(i%3==0){
}else{
break;
System.out.print('F');
System.out.print('T');
return(i%3);
continue;
do {
if(i%3>0){
// if 文の条件が満たされなければ, 次の { } を実行
// この2つが必須なのは考えるまでもない
//
// もし i%3 >0 なら 次の { } を実行
class Ex4
{
public static void main(String[] args)
{
int[] test1 = {80,60,47,4};
int[] test2 = test1;
for(int i=0; i< test2.length; i++){
System.out.print(test2[i]);// ここ
}
}
}
class Ex4
{
public static void main(String[] args)
{
int[] test1 = {80,60,47,4};
int[] test2 = test1;
for(int i=0; i< test2.length; i++){
System.out.print(test2[test2.length-i-1]); // -i なので、逆順
}
}
}
class Ex5
{ // 2 行
public static void main(String[] args)
{ // 4 行
int[] test ={70,55,85,90,70};
for(int i = 0; i <= test.length; ){ // i <= test.length では、
// インデックスが上限を超えてしまう。
System.out.println( // 7行
(i+1)"番目の人の点数は"+ // (i+1) の後に + がない。
test[i++]+"です。"); // 普通forにあるi++ がここにきている。無問題
} // 10行
System.out.println(
"テストの受験者は"+
test.length+"人です。");
} // 14行
}
[問7]
int[] test = new int[5];
int k=3;
for(int i=0; i<test.length; i++){
// ここの場所での各変数の値を表Aに書く
k = (k * 5) % 7; // k の値が変わるのはここだけ
test[i] = k;
System.out.print(k);
// ここの場所での各変数の値を表Bに書く
}
表A
i=
0
1
2
3
4
k=
3
1
5
4
6
test[i]
0
0
0
0
0
表B
i=
0
1
2
3
4
k=
1
5
4
6
2
test[i]
1
5
4
6
2
[問7] 次の部分は並べ替え
for(int i=0; i<test.length; i++){
for(int j=i+1; j<test.length; j++){ // test[i]に、test[i]~test[4] の最大値
if(test[j] > test[i]){
// が入るように並べ替え
int tmp = test[j];
test[j] = test[i];
test[i] = tmp;
}
}
// この場所での test[ ] の中身を下の表に書く
}
test[0]
test[1]
test[2]
test[3]
test[4]
for の前 1
6
4
5
2
i=0
6
1
4
5
2
i=1
6
5
1
4
2
i=2
6
5
4
1
2
i=3
6
5
4
2
1
i=4
6
5
4
2
1
[問7] int k=6;
if(test[j] < test[i]){ と書き換え後も同様。
int[] test = new int[5];
int k=6;
for(int i=0; i<test.length; i++){
// ここの場所での各変数の値を表Aに書く
k = (k * 5) % 7; // k の値が変わるのはここだけ
test[i] = k;
System.out.print(k);
// ここの場所での各変数の値を表Bに書く
}
前の例と見比べれば気づくかも?
k は 1, 5, 4, 6, 2, 3 の繰り返し
表A
i=
0
1
2
3
4
k=
6
2
3
1
5
test[i]
0
0
0
0
0
表B
i=
0
1
2
3
4
k=
2
3
1
5
4
test[i]
2
3
1
5
4
[問7] 次の部分は並べ替え
for(int i=0; i<test.length; i++){
for(int j=i+1; j<test.length; j++){ // test[i]に、test[i]~test[4] の最大値
if(test[j] > test[i]){
// が入るように並べ替え
int tmp = test[j];
test[j] = test[i];
test[i] = tmp;
}
}
// この場所での test[ ] の中身を下の表に書く
}
test[0]
test[1]
test[2]
test[3]
test[4]
forの前
2
3
1
5
4
i=0
1
3
2
5
4
i=1
1
2
3
5
4
i=2
1
2
3
5
4
i=3
1
2
3
4
5
i=4
1
2
3
4
5
次のプログラムについて、問に答えよ。
class Ex1
{
static int scramble(int input, int keynum){
// 上の static の意味は考えなくて良い。計算を追うのに支障ない。基礎IIの範囲。
int NP1 = 10000;
int[] key = {137,73};
return (input * key[keynum] % NP1);
}
public static void main(String[] args) {
int data = 【初期値】;
for(int n=0; n<10; n++){
data=scramble(data,0);
}
for(int n=0; n<【?】; n++){
data=scramble(data,1);
}
System.out.println(data);
}
}
問1 プログラムを入力して動かす前に、まず
次のことを考えよ。 【初期値】を各人の学籍番
号の下3ケタとしたとき、最初の for 文(赤色に
着色した部分)中での、変数 data の値の変
化を表にせよ。
 問2 問1 と同様にして、2番目の for 文(緑色
に着色した部分)中での、変数 data の値の
変化を表にせよ。ただし、【?】には、プログラ
ム実行時に初期値が印字される数を入れる。
(data の値が【初期値】に戻るまで、表を埋め
続ければ、【?】に入るべき数が見つかる。)
 問3 プログラムを動かして動作を確認せよ。


問4 Ex1.java の scramble メソッドをコピーし
て、以下の機能を持つEx2.java を作成せよ。
scramble(scramble(k,0),1) != k
 1<= k かつ k<10000
となる整数 k を探しだして印字する。そのようなkが
なければ"見つからない" と表示する。


また、Ex2.java をコンパイル、実行して実際にそのよ
うな整数 k を答えよ。(そのような k はない、という答
えもありうる)