演習の解答

第一回

演習 1-1

Hello World と表示される

演習 1-2

  1. 
    #include <stdio.h>
    #define N 5
    main(){
      int i,j;
      for(i=0;i<N;i++){
        for(j=0;j<N-i;j++){
          printf("○");
        }
        printf("\n");
      }
    }
    
  2. 
    #include <stdio.h>
    #define N 4
    main(){
      int i,j;
      for(i=0;i<N;i++){
        for(j=0;j<N-i-1;j++){
          printf(" ");
        }
        for(j=0;j<2*i+1;j++){
          printf("○");
        }
        printf("\n");
      }
    }
    
  3. 
    #include <stdio.h>
    #define N 3
    main(){
      int i,j;
      for(j=0;j<N+2;j++){
        printf("○");
      }
      printf("\n");
      for(i=0;i<N;i++){
        printf("○");
        for(j=0;j<N;j++){
          printf(" ");
        }
        printf("○\n");
      }
      for(j=0;j<N+2;j++){
        printf("○");
      }
    }
    

第二回

演習 2-1

  1. 
    #include <stdio.h>
    main(){
      int a[]={5, 2, 6, 3, 1, -1};
      int i,k;
      k=0;
      for(i=0;a[i]!=-1;i++){
        k++;
      }
      printf("%d\n",k);
    }
    
  2. 
    #include <stdio.h>
    main(){
      int a[]={5, 2, 6, 3, 1, -1};
      int i,goukei;
      goukei=0;
      for(i=0;a[i]!=-1;i++){
        goukei+=a[i];
      }
      printf("%d\n",goukei);
    }
    
  3. 
    #include <stdio.h>
    main(){
      int a[]={5, 2, 6, 3, 1, -1};
      int i,k,goukei;
      k=0;
      goukei=0;
      for(i=0;a[i]!=-1;i++){
        k++;
        goukei+=a[i];
      }
      printf("%f\n",(float)goukei/k);
    }
    

第三回

演習 3-1

  1. 
    #include <stdio.h>
    main(){
      char x[]="abc";
      int i,k;
      k=0;
      for(i=0;x[i]!='\0';i++){
        k++;
      }
      printf("%d\n",k);
    }
    
  2. 
    #include <stdio.h>
    main(){
      char x[]="This is a pin.";
      int i,k;
      k=0;
      for(i=0;x[i]!='\0';i++){
        if(a[i]=='i'){
          k++;
        }
      }
      printf("%d\n",k);
    }
    
  3. 
    #include <stdio.h>
    main(){
      char x[]="This is a pin.";
      int i;
      char c;
      for(i=0;x[i]!='\0';i++){
        c=x[i];
        if((c>='a')&&(c<='z')){
          c=c-'a'+'A';
        }
        printf("%c",c);
      }
    }
    
  4. 
    #include <stdio.h>
    main(){
      char x[]="abc";
      char y[]="def";
      char z[50];
      int i,j;
      for(i=0;x[i]!='\0';i++){
        z[i]=x[i];
      }
      for(j=0;y[j]!='\0';j++){
        z[i]=y[j];
        i++;
      }
      z[i]='\0';
      printf("文字列 %s と %s をつなげると %s になる\n",x,y,z);
    }
    

第四回

    1. i=2, j=1
    2. i=1. j=0
    3. i=0
  1. #include <stdio.h>
    main(){
      FILE *fh;
      char filename[]="4-2.c";
      char c;
      int n=0;
      if((fh=fopen(filename,"r"))!=NULL){
        while((c=getc(fh))!=EOF){
          n++;
        }
        printf("合計 %d 文字\n",n);
        fclose(fh);
      }else{
        fprintf(stderr,"ファイル %s を開けませんでした\n",filename);
      }
    }
    
  2. #include <stdio.h>
    main(){
      FILE *fh;
      char filename[]="4-3.c";
      char c;
      char x='a';
      int n=0;
      if((fh=fopen(filename,"r"))!=NULL){
        while((c=getc(fh))!=EOF){
          if(c==x){
            n++;
          }
        }
        printf("%c は合計 %d 文字\n",x,n);
        fclose(fh);
      }else{
        fprintf(stderr,"ファイル %s を開けませんでした\n",filename);
      }
    }
    
  3. #include <stdio.h>
    main(){
      FILE *fh;
      char filename[]="4-4.c";
      char c;
      int n=0;
      if((fh=fopen(filename,"r"))!=NULL){
        while((c=getc(fh))!=EOF){
          if(c=='\n'){
            n++;
          }
        }
        printf("合計 %d 行\n",n);
        fclose(fh);
      }else{
        fprintf(stderr,"ファイル %s を開けませんでした\n",filename);
      }
    }
    
  4. #include <stdio.h>
    main(){
      FILE *fh;
      char filename[]="4-5.c";
      char c;
      int n=0;
      if((fh=fopen(filename,"r"))!=NULL){
        while((c=getc(fh))!=EOF){
          n++;    
          if(c=='\n'){
            printf("%d 文字\n",n);
            n=0;
          }
        }
        if(n!=0){
          printf("%d 文字\n",n);
        }
        fclose(fh);
      }else{
        fprintf(stderr,"ファイル %s を開けませんでした\n",filename);
      }
    }
    
  5. #include <stdio.h>
    main(){
      FILE *fh;
      char filename[]="4-6.c";
    
      char c;
      int n=0;
      if((fh=fopen(filename,"r"))!=NULL){
        while((c=getc(fh))!=EOF){
          if(c=='\n'){
            printf("\n");
            n=0;
          }else{
            if(n>=10){
              printf("\n");
              n=0;
            }
            printf("%c",c);
            n++;
          }      
        }      
        fclose(fh);
      }else{
        fprintf(stderr,"ファイル %s を開けませんでした\n",filename);
      }
    }
    
  6. #include <stdio.h>
    #define N 3
    main(){
      FILE* fh;
      int i,j;
      if((fh=fopen("zukai.txt","w"))==NULL){
        fprintf(stderr,"ファイルを開けませんでした\n");
        exit(1);
      }
      for(i=0;i<N;i++){
        for(j=0;j<N-i-1;j++){
          fprintf(fh,"  ");
        }
        fprintf(fh,"○");
        if(i>0){
          for(j=0;j<2*i-1;j++){
    	fprintf(fh,"  ");
          }
          fprintf(fh,"○");
        }
        fprintf(fh,"\n");
      }
      for(i=N-2;i>=0;i--){
        for(j=0;j<N-i-1;j++){
          fprintf(fh,"  ");
        }
        fprintf(fh,"○");
        if(i>0){
          for(j=0;j<2*i-1;j++){
    	fprintf(fh,"  ");
          }
          fprintf(fh,"○");
        }
        fprintf(fh,"\n");
      }
      fclose(fh);
    }
    

第五回

演習 5-5


#include <stdio.h>
main(){
  char x[]="abcdef";
  char y[50];
  char *p,*q;
  p=x;
  q=y;
  while((*q++=*p++)!='\0');
  printf("%s をコピーした結果 %s となる\n",x,y);
}

演習 5-6


#include <stdio.h>
void copy(char *a, char *b){
  while((*b++=*a++)!='\0');
}
main(){
  char x[]="abcdef";
  char y[50];
  copy(x,y);
  printf("%s をコピーした結果 %s となる\n",x,y);
}

第六回

演習 6-1

----distance.c----

#include "point.h"
#include <math.h>
double distance(POINT p){
   return sqrt(p.x*p.x+p.y*p.y);
}

演習 6-2

----half.c----

#include "point.h"
void half(POINT *p){
  p->x /= 2;
  p->y /= 2;
}

第七回

演習 7-1

5!=120, 6!=720

演習 7-2

  1. 
    #include <stdio.h>
    int fibo(int n){
      if(n==0){ return 1; }
      if(n==1){ return 1; }
      return fibo(n-1)+fibo(n-2);
    }
    main(){
      printf("%d\n",fibo(20));
    }
    

    10946

  2. 
    #include <stdio.h>
    #define N 100
    int a[N];
    int fibo(int n){
      if(a[n]>0){ return a[n];}
      if(n==0){ return 1; }
      if(n==1){ return 1; }
      a[n]=fibo(n-1)+fibo(n-2);
      return a[n];
    }
    main(){
      int i;
      for(i=0;i<N;i++){a[i]=0;}
      printf("%d\n",fibo(45));
    }
    

    a40=165580141

    但し、演習室の環境だと簡単に求まってしまったため、 a45の値 1836311903 も求めた。

演習 7-3


#include <stdio.h>
int combi(int n, int m){
  if(m==0){ return 1; }
  if(m==n){ return 1; }
  return combi(n-1,m-1)+combi(n-1,m);
}
main(){
  printf("%d, %d\n",combi(5,2),combi(20,2));
}

10, 190 が表示される

演習 7-4

hanoi(3,'a','b','c')
move 1 from a to b
move 2 from a to c
move 1 from b to c
move 3 from a to b
move 1 from c to a
move 2 from c to b
move 1 from a to b
hanoi(4,'a','b','c')
move 1 from a to c
move 2 from a to b
move 1 from c to b
move 3 from a to c
move 1 from b to a
move 2 from b to c
move 1 from a to c
move 4 from a to b
move 1 from c to b
move 2 from c to a
move 1 from b to a
move 3 from c to b
move 1 from a to c
move 2 from a to b
move 1 from c to b

第八回

演習 8-1

14種類。

演習 8-2

0110
1010
1101
0010

演習 8-3


#include 
#define MAX 10
main(){
  int i,j,degree,kiten;
  int a[MAX][MAX];
  printf("頂点数を入れて下さい。\n");
  scanf("%d",&n);
  kiten=0;
  for(i=0;i<n;i++){
    degree=0;    
    for(j=0;j<n;j++){
      scanf("%d",&a[i][j];);
      degree+=a[i][j];
    }
    kiten+=degree%2
  }
  if((kiten==0)||(kiten==2)){
    printf("一筆書きできます。\n");
  }else{
    printf("一筆書きできません。\n");
  }
}

第九回

演習 9-1


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 80
char buffer[SIZE+1];
typedef struct lst {
  char *item;
  struct lst *next;
} LIST;
LIST* newnode(){
   LIST *p;
   p=(LIST *)malloc(sizeof(LIST));
   p->next=NULL;
   return p;
}
void add(LIST *p,char *c){
  if(p->next == NULL){
    p->item=c;
    p->next=newnode();
  }else{
    add(p->next,c);
  }
}  
void reverseshow(LIST *p){
  if(p->next != NULL){
    reverseshow(p->next);
    printf("%s\n",p->item);
  }
}
main(){
  char c;
  int i=0;
  char filename[]="input.txt";
  FILE *fh;
  LIST *l;
  l=newnode();
  if((fh=fopen(filename,"r"))!=NULL){
    while((c=getc(fh))!=EOF){
      if(c!='\n'){
	if(i<SIZE){
	  buffer[i++]=c;
	}
      }else{
	buffer[i]='\0';
	add(l,strdup(buffer));
	i=0;
      }
    }
    reverseshow(l);
    fclose(fh);
  }else{
    fprintf(stderr,"ファイル %s がありません。\n",filename);
  }
}

演習 9-2

作成中

第十回

演習 10-1

次のように出力される

def
ghi
abc

演習 10-2

例 2 と重複

演習 10-3

作成中

第十一回

演習 11-1

作成中

演習 11-2

show 関数を以下のように書き直す。


void show(TREE *t){
  if(t!=NULL){
    show(t->right);
    printf("%s: %d\n",t->id,t->key);
    show(t->left);
  }
}

演習 11-3

演習 11-4

第十二回

演習 12-1


#include <stdio.h>
int a[11]={4,6,3,1,9,7,5,0,2,6,8};
void printarray(){
  int i;
  for(i=0;i<11;i++){
    printf("%d ",a[i]);
  }
  printf("\n");
}
void partition(int s, int t){
  if(s<t){
    int val = a[s];
    int i=s+1,j=t;
    int tmp;
    while(i<=j){
      while((i<=t)&&(val>=a[i])){i++;}
      while((j>=s+1)&&(val<a[j])){j--;}
      if(i<j){
	tmp=a[i];
	a[i]=a[j];
	a[j]=tmp;
      }
    }
    if(i-1>=s+1){
      tmp=a[s];
      a[s]=a[i-1];
      a[i-1]=tmp;
    }
    partition(s,i-2);
    partition(j+1,t);
  }
}
main(){
  printarray();
  partition(0,10);
  printarray();
}

坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科