【Question 1-1】
次の実行結果を答えよ
int[] a = { 2, 1, 0 };
int[] b = { 3, 4, 5 };
int c = 2;
System.out.println( b[ a[ c ] ] );
解答へ
【Question 1-2】
次の実行結果を答えよ
int a = 1;
int b = 2;
int c = 3;
System.out.println( ( a > c )? ( ( a > b )? a : b ) : ( ( c > b )? c : b ) );
解答へ
【Question 1-3】
次の実行結果を答えよ
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = 3;
int d = add( add( a, b ), add( c, add( b, c ) ) );
System.out.println( d );
}
static int add( int x, int y ) {
return x + y;
}
解答へ
【Question 1-4】
次の実行結果を答えよ
static int[] num = new int[ 10 ];
public static void main(String[] args) {
num[ 0 ] = 5;
recursion( 0 );
for( int i : num )System.out.print( i + " " );
}
static void recursion( int index ) {
if( num[ index ] > 0 ) {
num[ index + 1 ] = num[ index ] - 1;
recursion( index + 1 );
}
}
解答へ
【Question 1-5】
次の実行結果を答えよ。
【1-4】を2次元にして上下左右で再帰呼出ししている。
少し複雑になるので参考程度に
static int[][] map = new int[ 10 ][ 12 ];
public static void main( String[] args ) {
map[ 5 ][ 6 ] = 5;
drawMap();
recursion( 5, 6 );
drawMap();
}
static void recursion( int indexY, int indexX ) {
int[] directionX = { 1, 0, -1, 0 };
int[] directionY = { 0, 1, 0, -1 };
for( int d = 0; d < directionX.length; d++ ) {
int x = indexX + directionX[ d ];
int y = indexY + directionY[ d ];
if( x < 0 || map[ 0 ].length - 1 < x || y < 0 || map.length - 1 < y ) continue;
if( map[ y ][ x ] < map[ indexY ][ indexX ] && map[ indexY ][ indexX ] > 0 ) {
map[ y ][ x ] = map[ indexY ][ indexX ] - 1;
recursion( y, x );
}
}
}
static void drawMap() {
for( int y = 0; y < map.length; y++ ) {
for( int x = 0; x < map[ 0 ].length; x++ ) {
System.out.print( map[ y ][ x ] + " " );
}
System.out.print( "\n" );
}
System.out.print( "\n" );
}
解答へ
【1-1 解答】
3
b[ a[ c ] ] まず c = 2 なので
b[ a[ 2 ] ] 次に a[ 2 ] = 0 なので
b[ 0 ] となり答えは3。
問題に戻る
【1-2 解答】
3
( a > c )? ( ( a > b )? a : b ) : ( ( c > b )? c : b )
()が多くてわかりづらいが3項演算子を3つ使っている。説明の都合上後ろから見ていく。
( c > b )? c : b を中に入っている数値に置き換えると ( 3 > 2 )? 3 : 2 よって3になる。
( a > b )? a : b も同様に ( 1 > 2 )? 1 : 2 で2になる。
最終的に
( a > c )? 2 : 3 となり ( 1 > 3 )? 2 : 3 は3になる。
3項演算子を式の一部として使う場合、()で括るのが安全。括らないと予期せぬ動作をすることがある。
問題に戻る
【1-3 解答】
11
メソッドの引数にメソッドを使っている。まず a,b,c を数値に置き換える
add( add( 1, 2 ), add( 3, add( 2, 3 ) ) )
最後尾の add から見ていく。戻り値は 2+3=5 なので
add( add( 1, 2 ), add( 3, 5 ) )
add( 3, 5 ) は8なので
add( add( 1, 2 ), 8 )
add( 1, 2 ) は3なので
add( 3, 8 ) となり答えは11
1つずつ追っていけば難しくはない。
問題に戻る
【1-4 解答】
5 4 3 2 1 0 0 0 0 0
recursion メソッドの中で recursion メソッドを呼び出している。
こうして自分自身を呼び出すことを再帰呼出しという。
呼び出されるたびに index は +1 されそこに入る数値は -1 される。
数値が 0 になると次の再帰は行われずにメソッドから抜ける
自分自身を呼び出しても変数(int index)は呼出し先で新たに作られるので
実質別のメソッドを呼び出しているのと変わらない。
メソッドから抜ける条件を付けないとメソッド→メソッド→…の無限ループになり
メモリを大量に消費して StackOverflowError が出る。
問題に戻る
【1-5 解答】
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 2 1 0 0 0 0
0 0 0 0 1 2 3 2 1 0 0 0
0 0 0 1 2 3 4 3 2 1 0 0
0 0 1 2 3 4 5 4 3 2 1 0
0 0 0 1 2 3 4 3 2 1 0 0
0 0 0 0 1 2 3 2 1 0 0 0
0 0 0 0 0 1 2 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
static void recursion( int indexY, int indexX ) {
// 4方向の向き
int[] directionX = { 1, 0, -1, 0 };
int[] directionY = { 0, 1, 0, -1 };
// 4方向で探索
for( int d = 0; d < directionX.length; d++ ) {
// 文が長くなるので短い変数名に代入
int x = indexX + directionX[ d ];
int y = indexY + directionY[ d ];
// map の範囲外に出たら次の処理にいかない
if( x < 0 || map[ 0 ].length - 1 < x || y < 0 || map.length - 1 < y ) continue;
// 移動先が移動元より小さいか判定
if( map[ y ][ x ] < map[ indexY ][ indexX ] && map[ indexY ][ indexX ] > 0 ) {
// 移動先に(移動元の数値 -1 )を代入
map[ y ][ x ] = map[ indexY ][ indexX ] - 1;
// 再帰呼出し
recursion( y, x );
}
}
}
コメントを入れて見た。
これで何ができるかというと、シミュレーションゲームなどでキャラの移動範囲がわかる。
移動先のマスから数が増える方向に辿っていくと経路もわかる。
1マス移動するのに2歩必要な地形なども考慮するともう少し書き足す必要がある。
ぷよぷよでは再帰呼出しで同じぷよが隣接しているか判定して隣接した個数もカウントする。
他にも迷路の探索やフラクタル図形の描画などができる。
問題に戻る
メモ