【C言語】基本情報技術者・午後過去問・解答例(2019春)

基本情報技術者・午後過去問(2019春)・解答例についてソースコード付きで解説します。

【問題1】平成31年 春期 基本情報技術者 午後 問09

次のC言語プログラムの説明及びプログラムを読んで,設問1,2に答えよ。

入力ファイルを読み込んで,文字コードごとの出現回数を印字するプログラムである。

〔プログラムの説明〕
(1) 入力ファイルは,バイナリファイルとして読み込む。 入力ファイル中の各バイトの内容(ビット構成)に制約はない。入力ファイル名は,#define で指定する。
(2) 入力ファイル中の各バイトについて,文字コード(16 進数 00 ~ FF で表示する)ごとの出現回数を求めて印字する。印字例を,図1に示す。
(3) 印字様式を次に示す(①~③は,プログラム中の記号を指している)。1 行目に,処理したバイト数を①の形式で印字する。3 行目以降に,出現回数とその文字コードを②の形式で印字する。 ただし,文字コードが 20~ 7E の場合は,文字コードの後にそれが表す文字(文字は, この冊子の末尾にあるアセンブラ言語の仕様の 1.3 で規定するもの)を③の形式で印字する。文字コードは,64 行× 4 列の範囲に,上から下, 左から右に文字コードの昇順となるように並べる。
(4) プログラム中で使用している関数 fgetc(s) は,ストリーム s から1文字を読み込んで返す。 ストリームが入力ファイルの終わりに達しているときは EOF を返す。
(5) 入力ファイルのサイズは,long 型(32 ビットとする)で表現できる数値の範囲を超えないものとする。
        870 bytes processed・・・①

          0 00          0 40 '@'          0 80          0 C0
          0 01・・・②   0 41 'A' ・・・③   1 81          0 C1
          0 02          0 42 'B'          3 82          0 C2
          0 03          1 43 'C'          4 83          0 C3
︙
          1 3E '>'          0 7E '~'          1 BE          0 FE
          0 3F '?'          0 7F          0 BF          0 FF
          0 40 '@'          0 80          0 C0 1985365600 100

プログラム

#include <stdio.h>

#define InName "sample.c"/* 入力ファイル名 */


int main() {
    FILE   *infile;
    int    chr, i;
    long   cnt;
    long   freq[256];   /* freq[i]: 文字コード i の出現回数 */

    for (chr = 0; chr <= 255; chr++)
    freq[chr] = 0;


    infile = fopen(InName, "rb");
    cnt = 0;
    while ((chr = fgetc(infile)) != EOF) {
        cnt++;
        freq[chr]++;
    }
    fclose(infile);
    printf(" %10ld bytes processed\n\n", [a]);
    for (i = 0; i <= 64; i++) {
        for (chr = i; chr <= [b] ; chr += [c] ) {
            if ((0x20 <= chr) && (chr <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], chr, chr);
            else
            printf(" %10ld %02X", freq[chr], chr);
         }
        printf("\n");
    }

    return 0;
}
a に関する解答群
ア cnt – 1       イ cnt       ウ cnt + 1
 

b,c に関する解答群
ア 4         イ 64       ウ 256
エ i + 4       オ i + 64     カ i + 192

【解答1】

a=イb=カc=イ

#include <stdio.h>

#define InName "C:\\github\\sample\\cpp\\fe\\2018_2\\sample.c"/* 入力ファイル名 */


int main() {
    FILE   *infile;
    int    chr, i;
    long   cnt;
    long   freq[256];   /* freq[i]: 文字コード i の出現回数 */

    for (chr = 0; chr <= 255; chr++)
        freq[chr] = 0;


    infile = fopen(InName, "rb");
    cnt = 0;
    while ((chr = fgetc(infile)) != EOF) {
        cnt++;
        freq[chr]++;
    }
    fclose(infile);
    printf(" %10ld bytes processed\n\n", cnt);
    for (i = 0; i <= 64; i++) {
        for (chr = i; chr <= i + 192 ; chr += 64 ) {
            if ((0x20 <= chr) && (chr <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], chr, chr);
            else
            printf(" %10ld %02X", freq[chr], chr);
         }
        printf("\n");
    }

    return 0;
}
        870 bytes processed

          0 00          0 40 '@'          0 80          0 C0
          0 01          0 41 'A'          1 81          0 C1
          0 02          0 42 'B'          3 82          0 C2
          0 03          1 43 'C'          4 83          0 C3
          0 04          0 44 'D'          0 84          0 C4
          0 05          3 45 'E'          1 85          0 C5
          0 06          2 46 'F'          0 86          0 C6
          0 07          0 47 'G'          2 87          0 C7
          0 08          0 48 'H'          0 88          0 C8
          0 09          3 49 'I'          1 89          0 C9
         34 0A          0 4A 'J'          1 8A          0 CA
          0 0B          0 4B 'K'          0 8B          0 CB
          0 0C          1 4C 'L'          0 8C          0 CC
         34 0D          0 4D 'M'          1 8D          0 CD
          0 0E          2 4E 'N'          0 8E          0 CE
          0 0F          1 4F 'O'          1 8F          0 CF
          0 10          0 50 'P'          1 90          0 D0
          0 11          0 51 'Q'          0 91          0 D1
          0 12          0 52 'R'          0 92          0 D2
          0 13          0 53 'S'          0 93          0 D3
          0 14          0 54 'T'          0 94          0 D4
          0 15          0 55 'U'          2 95          0 D5
          0 16          0 56 'V'          1 96          0 D6
          0 17          0 57 'W'          1 97          0 D7
          0 18          2 58 'X'          0 98          0 D8
          0 19          0 59 'Y'          0 99          0 D9
          0 1A          0 5A 'Z'          0 9A          0 DA
          0 1B          6 5B '['          2 9B          0 DB
          0 1C         15 5C '\'          0 9C          0 DC
          0 1D          6 5D ']'          0 9D          0 DD
          0 1E          0 5E '^'          1 9E          0 DE
          0 1F          1 5F '_'          0 9F          0 DF
        250 20 ' '          0 60 '`'          0 A0          0 E0
          1 21 '!'          5 61 'a'          1 A1          0 E1
         12 22 '"'          3 62 'b'          0 A2          0 E2
          2 23 '#'         28 63 'c'          0 A3          8 E3
          0 24 '$'          7 64 'd'          1 A4          0 E4
          6 25 '%'         28 65 'e'          1 A5          6 E5
          2 26 '&'         23 66 'f'          0 A6          2 E6
          2 27 '''          4 67 'g'          0 A7          1 E7
         16 28 '('         20 68 'h'          0 A8          0 E8
         16 29 ')'         29 69 'i'          0 A9          0 E9
          5 2A '*'          0 6A 'j'          0 AA          0 EA
         10 2B '+'          0 6B 'k'          1 AB          0 EB
          8 2C ','         15 6C 'l'          0 AC          0 EC
          0 2D '-'          5 6D 'm'          1 AD          0 ED
          2 2E '.'         26 6E 'n'          1 AE          0 EE
          4 2F '/'          9 6F 'o'          0 AF          0 EF
         14 30 '0'         10 70 'p'          1 B0          0 F0
          5 31 '1'          6 71 'q'          0 B1          0 F1
          8 32 '2'         34 72 'r'          0 B2          0 F2
          0 33 '3'          8 73 's'          1 B3          0 F3
          2 34 '4'         15 74 't'          0 B4          0 F4
          3 35 '5'          3 75 'u'          0 B5          0 F5
          3 36 '6'          0 76 'v'          0 B6          0 F6
          1 37 '7'          1 77 'w'          0 B7          0 F7
          1 38 '8'          2 78 'x'          0 B8          0 F8
          1 39 '9'          1 79 'y'          0 B9          0 F9
          2 3A ':'          0 7A 'z'          1 BA          0 FA
         21 3B ';'          4 7B '{'          0 BB          0 FB
          6 3C '<'          0 7C '|'          1 BC          0 FC
         14 3D '='          4 7D '}'          0 BD          0 FD
          1 3E '>'          0 7E '~'          1 BE          0 FE
          0 3F '?'          0 7F          0 BF          0 FF
          0 40 '@'          0 80          0 C0 1985365600 100

【問題2】

次の記述中の に入れる正しい答えを, 解答群の中から選べ。ここで,記述中の と には,設問1の正しい答えが入っているものとする。
 

 文字コードを出現回数の降順に並べて印字する処理を追加する。追加した処理による印字例を, 図2に示す。印字の様式は,文字コードの並び順を除いて, 図1の3行目以降の様式と同じである。 同じ出現回数の文字コードは,それらを文字コードの昇順に並べる。

図2

追加した処理による印字例(出現回数順)

 

この処理のために,プログラムの行①の直後に,次の宣言を追加する。

 int  ih, ix, code[256];

 

さらに,プログラムの行②の位置に,次の整列処理部を追加する。
〔整列処理部〕

        for(i = Ø; i <=255; i++)
           code[i] = i;
③→    ih = 256;
④→    while (ih > Ø) {
⑤→       for(i = Ø; i < ih; i++) {
⑥→          if (freq[i] < freq[i+1]) {
                 Swap(code[i], code[i+1]);
                 Swap(freq[i], freq[i+1]);
⑦→
              }
           }
⑧→         ih--;
        }
        printf("\n");
        for (i =Ø; i < 64; i++) {
           for (chr = i; chr <=  ; chr +=  ) {
              if ((Øx2Ø <= code[chr]) && (code[chr] <= Øx7E))
                 printf(" %1Øld %Ø2X '%c'", freq[chr], code[chr], code[chr]);
              else
                 printf(" %1Øld %Ø2X     ", freq[chr], code[chr]);
           }
           printf("\n");
        }

 

ここで,整列処理部で使用する Swap(x, y) は,x と y の内容を入れ替えるために用意したマクロである。
整列処理部では,整列対象のデータ数が比較的少なく,また同じ出現回数の文字コードは 元の並び順が維持されるので,バブルソートを使用している。

行④の while 文のブロックを1回実行すると,配列の走査範囲(要素番号 0 ~ ih)中の 出現回数の最小値とその文字コードが,要素番号 ih の位置に置かれ,配列の走査範囲が 1 だけ狭められる。 これを繰り返して整列を行う。この処理では while 文のブロックの実行回数は常に[d]回となる。

ここで,while 文のブロックの1回の繰返しにおいて,行⑥の if 文のブロック内の処理が 最後に実行されたときの i の値を ix とすると,行⑤の for 文のブロックの実行が終了した時点で, 配列 freq の要素番号[e]以降の要素の値は整列済みとなっている。これを利用して, 整列処理部を表1に示すように変更すれば,while 文のブロックの実行回数を減らせる可能性がある。

整列処理部の変更内容 処置変更内容
[f]の直後に追加 ix = Ø
行⑦の位置に追加 ix = i;
行⑧を置換え [g]  
d に関する解答群
ア 253       イ 254       ウ 255       エ 256
 

e に関する解答群
ア 256-ix       イ ix-1       ウ ix       エ ix+1
 

f に関する解答群
ア 行③       イ 行④       ウ 行⑤
 

g に関する解答群
ア ih = ix - 1       イ ih = ix       ウ ih = ix + 1       エ ix = ih

【解答2】

ウエイイ
ix+1 行④ ih = ix

#include <stdio.h>

#define InName "C:\\github\\sample\\cpp\\fe\\2018_2\\sample2.c"/* 入力ファイル名 */

void Swap(int *x, int *y)
{
    int temp;
    temp = *x;  /* xが指す変数の値を退避 */
    *x = *y;    /* yが指す変数の値をxが指す変数に代入 */
    *y = temp;  /* tempに退避しておいたxが指す変数の値をyが指す変数に代入*/
}

int main() {
    FILE   *infile;
    int    chr, i;
    long   cnt;
    long   freq[256];   /* freq[i]: 文字コード i の出現回数 */
    int    ih, ix, code[256];

    for (chr = 0; chr <= 255; chr++)
        freq[chr] = 0;


    infile = fopen(InName, "rb");
    cnt = 0;
    while ((chr = fgetc(infile)) != EOF) {
        cnt++;
        freq[chr]++;
    }
    fclose(infile);
    printf(" %10ld bytes processed\n\n", cnt);
    for (i = 0; i <= 64; i++) {
        for (chr = i; chr <= i + 192 ; chr += 64 ) {
            if ((0x20 <= chr) && (chr <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], chr, chr);
            else
            printf(" %10ld %02X", freq[chr], chr);
         }
        printf("\n");
    }

    // ここから機能追加
    for(i = 0; i <=255; i++)
        code[i] = i;
    ih = 255;
    while(ih > 0) {
        for(i = 0; i < ih; i++) {
            if(freq[i] < freq[i+1]) {
                Swap(&code[i], &code[i+1]);
                Swap(&freq[i], &freq[i+1]);

            }
        }
        ih--;
    }

    printf("\n");

    for (i = 0; i < 64; i++) {
        for (chr = i; chr <= i + 192 ; chr += 64 ) {
            if ((0x20 <= code[chr]) && (code[chr] <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], code[chr], code[chr]);
            else
                printf(" %10ld %02X     ", freq[chr], code[chr]);
        }
        printf("\n");
    }
    return 0;
}
#include <stdio.h>

#define InName "C:\\github\\sample\\cpp\\fe\\2018_2\\sample2.c"/* 入力ファイル名 */

void Swap(int *x, int *y)
{
    int temp;
    temp = *x;  /* xが指す変数の値を退避 */
    *x = *y;    /* yが指す変数の値をxが指す変数に代入 */
    *y = temp;  /* tempに退避しておいたxが指す変数の値をyが指す変数に代入*/
}

int main() {
    FILE   *infile;
    int    chr, i;
    long   cnt;
    long   freq[256];   /* freq[i]: 文字コード i の出現回数 */
    int    ih, ix, code[256];

    for (chr = 0; chr <= 255; chr++)
        freq[chr] = 0;


    infile = fopen(InName, "rb");
    cnt = 0;
    while ((chr = fgetc(infile)) != EOF) {
        cnt++;
        freq[chr]++;
    }
    fclose(infile);
    printf(" %10ld bytes processed\n\n", cnt);
    for (i = 0; i <= 64; i++) {
        for (chr = i; chr <= i + 192 ; chr += 64 ) {
            if ((0x20 <= chr) && (chr <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], chr, chr);
            else
            printf(" %10ld %02X", freq[chr], chr);
         }
        printf("\n");
    }

    // ここから機能追加
    for(i = 0; i <=255; i++)
        code[i] = i;
    ih = 255;
    while(ih > 0) {
        ix = 0;
        for(i = 0; i < ih; i++) {
            if(freq[i] < freq[i+1]) {
                Swap(&code[i], &code[i+1]);
                Swap(&freq[i], &freq[i+1]);
                ix = i;
            }
        }
        ih = ix;
    }

    printf("\n");

    for (i = 0; i < 64; i++) {
        for (chr = i; chr <= i + 192 ; chr += 64 ) {
            if ((0x20 <= code[chr]) && (code[chr] <= 0x7E))
                printf(" %10ld %02X '%c'", freq[chr], code[chr], code[chr]);
            else
                printf(" %10ld %02X     ", freq[chr], code[chr]);
        }
        printf("\n");
    }
    return 0;
}
- 関連記事
1 【基本情報】C言語の午後過去問・解答例まとめ
2 【情報処理入門】テクノロジ系、マネジメント系、ストラテジ系、資格試験
3 【C言語入門】基本文法・サンプル集

コメント

  1. 匿名 より:

    ③→ ih = 256;
    は誤植ですよね?