基本情報技術者試験 C言語問題のソースコード(平成29年 秋期 )

このページでは平成29年秋期 基本情報技術者試験のC言語問題のソースコードを実際に実行できるようし、さらに実行時の動きの確認が行えるように変更したものを公開しています。C言語問題対策のためにも、こちらのソースコードをコピペして実際にプログラムを動作させ、どのように動作するのか、正解以外の選択肢を選んだ場合にどのような動きになって仕様を満たさないかを確認するために使用してみてください。

問題

平成29年秋期のC言語問題はIPAの下記ページで公開されています。

https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2017h29_2/2017h29a_fe_pm_qs.pdf

問題の解説

問題の解き方の解説は下記ページで行なっています。自分でプログラムの動きが追うのが困難な場合などに参考にしてください。

平成29年(H29)秋期 基本情報技術者試験 C言語問題 解き方解説

スポンサーリンク

設問1

C言語ソースコード

h29f_c_1.c
#include <stdio.h>
#include <ctype.h>

void find_palindrome(const char*);
int is_palindrome(const char*, int);
const char* find_char(const char*, char);

void find_palindrome(const char* text) {
  int i;
  int psize;
  const char* ith;
  const char* hit;
  for (i = 0; text[i] != '\0'; i++) {
    if (!isalnum(text[i])) {
      continue;
    }
    ith  = &text[i];
    hit = find_char(ith + 1, *ith);
    while (hit != NULL) {
      /* 設問1[a] */
      psize = hit - ith + 1;
      if (is_palindrome(ith, psize)) {
        while (ith < hit + 1) {
          putchar(*ith);
          ith++;
        }
        putchar('\n');
        return;
      }
      hit = find_char(hit + 1, *ith);
    }
  }
}

int is_palindrome(const char* chars, int size) {
  int l;
  int r;
  for (l = 0, r = size - 1; l < r; l++, r--) {
    while (!isalnum(chars[l])) {
      l++;
    }
    while (!isalnum(chars[r])) {
      r--;
    }
    /* 設問1[b] */
    if (tolower(chars[l]) != tolower(chars[r])) {
      return 0;
    }
  }
  return 1;
}

const char* find_char(const char* str, char ch) {
  int i;

  /* 動作確認用に追加 */
  printf("find_char : str = %s, ch = %c\n", str, ch);

  for (i = 0; str[i] != '\0'; i++) {
    /* 設問1[c] */
    if (tolower(ch) == tolower(str[i])) {
      return &str[i];
    }
  }
  return NULL;
}

int main(void) {
  char text[256] = "abc0cb1bc0cbe";
  find_palindrome(text);
}

実行方法

実行方法は、ソースコードをコンパイルして実行するだけです。main関数の中でfind_palindrome関数への入力文字列を作成していますので、この文字列を変更してコンパイルし直すことで異なった入力文字列時の動きを確認することが可能です。

実行結果

実行すると、下記のようにfind_char関数実行された時に、この関数が実行された時のstr、chの値が出力され、最終的に見つかった回文が表示されます。

find_char : str = bc0cb1bc0cbe, ch = a
find_char : str = c0cb1bc0cbe, ch = b
bc0cb

動作確認用の変更箇所

main関数追加

main関数ではfind_palindrome関数に入力する文字列textを用意し、find_palindrome関数を実行するだけのシンプルな作りになっています。文字列textを変更するとプログラムの動きが変わりますので色々試してみると良いと思います。

動作確認用の文字列出力追加

find_char関数の最初に引数として入力された変数の値を出力し、それぞれの引数の値がどのように変化していくかを追いやすくしています。

設問2・設問3

C言語ソースコード

h29f_c_2.c
#include <stdio.h>
#include <ctype.h>
#include <string.h>

void find_palindrome(const char*);
int is_palindrome(const char*, int);
const char* find_last_char(const char*, char, int);

void find_palindrome(const char* text) {
  int i;
  int psize;
  unsigned int textlen = strlen(text);
  const char* ith;
  const char* hit;
  for (i = 0; text[i] != '\0'; i++) {
    if (!isalnum(text[i])) {
      continue;
    }
    ith  = &text[i];
    hit = find_last_char(ith + 1, *ith, textlen - i - 1);
    while (hit != NULL) {
      /* 設問1[a] */
      psize = hit - ith + 1;
      if (is_palindrome(ith, psize)) {
        while (ith < hit + 1) {
          putchar(*ith);
          ith++;
        }
        putchar('\n');
        return;
      }
      /* 設問2[d] */
      hit = find_last_char(ith + 1, *ith, psize - 2);
    }
  }
}

int is_palindrome(const char* chars, int size) {
  int l;
  int r;
  for (l = 0, r = size - 1; l < r; l++, r--) {
    while (!isalnum(chars[l])) {
      l++;
    }
    while (!isalnum(chars[r])) {
      r--;
    }
    /* 設問1[b] */
    if (tolower(chars[l]) != tolower(chars[r])) {
      return 0;
    }
  }
  return 1;
}

const char* find_last_char(const char* str, char ch, int count) {
  int i;

  /* 動作確認用に追加 */
  printf("find_last_char : str = %s, ch = %c, count = %d\n", str, ch, count);

  /* 設問2[e] */
  for (i = count - 1; i >= 0; i--) {
    /* 設問1[c] */
    if (tolower(ch) == tolower(str[i])) {
      return &str[i];
    }
  }
  return NULL;
}

int main(void) {
  char text[256] = "No! Madam, I'm Adam Graham. This is my gym.";
  find_palindrome(text);
}

実行方法

設問1同様に実行方法は、ソースコードをコンパイルして実行するだけです。main関数の中でfind_palindrome関数への入力文字列を作成していますので、この文字列を変更してコンパイルし直すことで異なった入力文字列時の動きを確認することが可能です。

実行結果

実行すると、下記のようにfind_last_char関数実行された時に、この関数が実行された時のstr、ch、countの値が出力され、最後に見つかった回文が表示されます。

find_last_char : str = o! Madam, I'm Adam Graham. This is my gym., ch = N, count = 42
find_last_char : str = ! Madam, I'm Adam Graham. This is my gym., ch = o, count = 41
find_last_char : str = adam, I'm Adam Graham. This is my gym., ch = M, count = 38
find_last_char : str = adam, I'm Adam Graham. This is my gym., ch = M, count = 36
find_last_char : str = adam, I'm Adam Graham. This is my gym., ch = M, count = 31
find_last_char : str = adam, I'm Adam Graham. This is my gym., ch = M, count = 20
Madam, I'm Adam

動作確認用の変更箇所

main関数追加

設問1同様にmain関数ではfind_palindrome関数に入力する文字列textを用意し、find_palindrome関数を実行するだけです。文字列textを変更するとプログラムの動きが変わりますので色々試してみると良いと思います。

動作確認用の文字列出力追加

こちらも設問1のソースコード同様に、find_last_char関数の最初に引数として入力された変数の値を出力し、それぞれの引数の値がどのように変化していくかを追いやすくしています。

設問3はfind_last_char関数が実行される回数と、最後に実行された時の引数countの値が問われる問題ですので、考えてみたけど設問3の解答に辿り着けない方には、上記の出力が参考になると思います。

 

他の回のソースコード

他の回のソースコードについても下記ページで公開していますので、是非ソースコードを使用してプログラムの動きを見てみてください。

基本情報技術者試験C言語問題のプログラムを動かしてみよう(まとめ)

本ページのプログラムについて

プログラムはIPA公開の過去問題から引用し、さらに動作確認できるように必要な部分に関してのみ加工して使用させていただいております。

出典:平成29年度 秋期 基本情報技術者試験(FE)試験区分 午後 問9

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です