電子情報4年情報構造論96年度後期中間試験

教科書・ノート持ち込み不可。
解答に使用するプログラム言語は、 問題の趣旨に沿っていれば何を用いても良い。
解答を裏に書く場合、どの設問に対する答か解るようにすること。

すべての大きな設問の中から、4題以上について回答せよ。
採点は、各設問毎に行ない点数の高いものから4題について評価する。

4題よりより多く回答されている場合は、点数の 1/3 で加算する。


1.基礎(選択=20)

次に示すプログラムの実行結果を示せ。
	#include <stdio.h>
	int mat_a[ 4 ][ 4 ] = {
	    { 32,-1,22,-1 } , /* +→ y */
	    { -1,-1,-1,12 } , /* ↓\   */
	    { -1,22,-1,-1 } , /* x      */
	    { 30,-1,11, 0 }   /* mat_a[3][0]=30 */
	} ;
	int mat_b[ 4 ][ 4 ] = {
	    { 33,-1,31,-1 } ,
	    { 13,-1,-1, 2 } ,
	    { 12,-1,10,-1 } ,
	    { 58,-1,-9,22 }
	} ;
	int foo( int mat44[ 4 ][ 4 ] ) {
	    int  xy = 0 , x  = 0 , y = 0 ;
	    while( mat44[ x ][ y ] >= 0 ) {
	        xy = mat44[ x ][ y ] ;
	        x = xy / 10 ; /* 10で割った数   */
	        y = xy % 10 ; /* 10で割った余り */
	    }
	    return xy ;
	}
	void main() {
	    printf( "%d\n" , foo( mat_a ) ) ;
	    printf( "%d\n" , foo( mat_b ) ) ;
	}
	

2.双方向リスト(選択=20)

	#define NEW(T) (T*)malloc(sizeof(T))
	struct List2 {
	    struct List2* prev ;
	    int   data ;
	    struct List2* next ;
	} ;
	struct List2 top  = { NULL ,     0 , NULL } ,
	             tail = { NULL , 99999 , NULL } ;
	void insert( struct List2* dest , int datum ) {
	    struct List2* p = NEW( struct List2 ) ;
	    struct List2* n = p->next ;
	    p->prev = dest ;
	    p->next = n ;
	    dest->next = p ;
	    n->prev    = p ;
	}
	void del( struct List2* p ) {
	    /* p の後ろにあるデータを消す */
	    /* この部分を記述せよ */
	}
	void main() {
	    insert( &top , 10 ) ; /* 処理1 */
	    insert( &top , 20 ) ; /* 処理2 */
	    del( &top ) ; /* topの次のデータを消したい */
	    del( &top ) ; /* さらにtopの次のデータを消したい */
	}
	
  1. 処理2 が終了時点での、リスト構造のメモリ状況のイメージを、図示せよ。
  2. プログラム中の、リストを1件消す del(struct List2*) を 作成せよ。ただし、先頭(top)や末尾(tail)を消すことは考えなくて良い。

3.効率の比較(必須=30)

次に示す3つの方法によって、データベースを作成した。
	#define MAXSIZE 200
	typedef ...... SomeData ; /* 何らかのデータ構造の定義 */

	SomeData[ MAXSIZE ] ; /* (a) 配列に昇順に格納し2分探索する */
	int size ;                    /* データ件数:N */

	struct SimpleList {   /* (b) 単純リスト方式 */
	    SomeData           data ; /* データ */
	    struct SimpleList* next ; /* 次のデータへのポインタ */
	} ;

	struct Tree2 {        /* (c) 2分木方式 */
	    SomeData      data ;  /* データ */
	    struct Tree2* left ;  /* data より小さな2分木へのポインタ */
	    struct Tree2* right ; /* data より大きな2分木へのポインタ */
	} ;
	
  1. データベースの設計するために(a)方式と(c)方式において、 メモリの使用量を最小限にすることを目標に、 どちらかの方式を選択したい。 SomeData の1件あたりのデータ量は 20[byte]かかり、 その2分木の Tree2 では、 1件あたり(SomeDataを含んで) 32[byte]かかるものとする。 データベースの通常のデータ件数が 150 件であれば、 どちらの方式を採用すべきか理由を述べて説明せよ。
  2. (a)方式と(b)方式において、データを探すプログラムの平均処理速度を 比較した所、データ件数 N=100 件において、 (a)方式は 0.05msec 、(b)方式は 0.01msec であった。
    処理速度を最優先でプログラムを選択する場合、 (a)方式が優れているのは、データ件数が何件以上か? 件数を(理由の説明を付けて)数式で示せ。

4.リスト構造応用(選択=20)

身長と名前のデータベースを、次のような構造体で定義し、 データベースの追加登録のプログラム insert(int,char*) を 作成した。この追加プログラムを参考に、このデータ構造の中から、 特定の身長の人をすべて表示するプログラムを作成せよ。
# 同じ身長の人は複数いる可能性があるとする。

	#define NEW(T) (T*)malloc(sizeof(T))
	struct NHList {
	    int            hight ;
	    char           name[ 20 ] ;
	    struct NHList* next ;
	} ;
	struct NHList* table[26] ;
	void insert( int h , char* n ) {
	    struct NameHight* p = NEW( struct NHList ) ;
	    p->hight = h ;
	    strcpy( p->name , n ) ;
	    p->next = table[ h / 10 ] ;
	    table[ h / 10 ] = p ;
	}
	void search( int h ) { /* h:身長 */
	    /* この部分を作ること */
	}
	void main() {
	    int  i = 0 ;
	    for( i = 0 ; i < 26 ; i++ )
	        table[ i ] = NULL ; /* 初期化 */
	    insert( 172 , "t-saitoh" ) ;
	    insert( 194 , "c3p0" ) ;
	    insert(  98 , "r2d2" ) ;
	    insert( 191 , "obi-one" ) ;
	    search( 194 ) ; /* c3p0 だけ表示される予定 */
	}
	


5.2分木応用(選択=20)

次のプログラムの動作結果について、答えよ。
	#define NEW(T) (T*)malloc(sizeof(T))
	struct Expr {
	    char  opr ;
	    int   x ;
	    struct Expr* left ;
	    struct Expr* right ;
	} ;
	struct Expr* num( int dat ) {
	    struct Expr* p = NEW( struct Expr ) ;
	    p->opr = 'N' ;
	    p->x = dat ;
	    p->left = p->right = NULL ;
	    return p ;
	} ;
	struct Expr* op( char y, struct Expr* l, struct Expr* r ) {
	    struct Expr* p = NEW( struct Expr ) ;
	    p->opr = y ;
	    p->x   = 0 ;
	    p->left = l ; p->right = r ;
	    return p ;
	} ;
	int eval( struct Expr* p ) {
	    switch( p->opr ) {
	    case 'N' : return p->x ;
	    case '+' : return eval( p->l ) + eval( p->r ) ;
	    case '*' : return eval( p->l ) * eval( p->r ) ;
	    }
	}
	void main() {
	    struct Expr* t = op( '+' ,
	                         num( 2 ) ,
	                         op( '*' , num( 3 ) , num( 4 ) ) ) ;
	    print( "%d\n" , eval( t ) ) ;
	} ;
	

6.説明問題(選択=20)

以下の用語について、具体例を上げて説明せよ。
  1. unixにおけるリダイレクトについて説明せよ。
  2. AVLについて説明せよ。(図等を交えて判りやすく説明すること)