基本情報技術者試験の過去問と解説
[TOP] [午前分野別] [午後分野別] [キーワード索引] [令和元年秋午前] [令和元年秋午後]

平成20年 秋期 基本情報技術者 午後 問12
問12   Java

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

(Javaプログラムで使用する API の説明は,この冊子の未尾を参照してください。)

〔プログラムの説明〕

 文字列照合用パターン(以下,パターンという)と,与えられた文字列を照合する プログラムである。パターン及び与えられた文字列は0個以上の文字からなる文字列である。 パターンを構成する文字には,照合するときに特殊な意味をもつ文字(以下, メタ文字という)及びメタ文字以外の文字(以下,通常文字という)がある。 表1にメタ文字とその意味を示す。

   表1 メタ文字とその意味

メタ文字      意味 
  ^  文字列の先頭に一致   
  .  任意の1文字に一致 
  $  文字列の末尾に一致 

 通常文字は,その文字と一致する。例えば,通常文字 'a' は1文字の a に一致する。

 与えられた文字列の全部又は一部にパターン全体が一致した場合,一致したものと判定する。 パターンの文字数が0のとき,すべての文字列に一致する。表2にパターンと そのパターンに一致する文字列及び一致しない文字列の例を示す。

   表2 パターンとそのパターンに一致する文字列及び一致しない文字列の例

 パターン   一致する文字列の例    一致しない文字列の例
 ""  "", "home"  なし
 "home"  "home", "tachometer"  "how", "hope", "me"
 "^ho.e"  "home", "hope", "hotel"  "hot", "hook", "shore"
 "ho..$"  "home", "hope", "shore"  "hop", "hotel", "hobby"   

 プログラムは,与えられたパターンを1文字ずつ解析し,照合処理がしやすい形式に変換する。 この解析及び変換処理をコンパイルと呼び,変換された照合処理の単位をパターン要素と呼ぶ。 メタ文字は,そのメタ文字の意味を表すパターン要素に変換され, 通常文字は,その文字を表すパターン要素に変換される。パターン全体は, パターン要素のリストで表される。例えば,パターン"^ho.e" は,'^', 'h', 'o', '.' 及び 'e' に分けられ,それぞれが次のパターン要素に変換される。

@ 文字列の先頭を表すパターン要素

A 'h' を表すパターン要素

B 'o' を表すパターン要素

C 任意の1文字を表すパターン要素

D 'e' を表すパターン要素

 次に,パターンと与えられた文字列との照合を,パターン要素のリストを評価しながら行う。 リスト中のパターン要素(前の例では@〜D)と,与えられた文字列の先頭の文字から順に照合し, 連続してすべてのパターン要素が一致したとき,パターンは与えられた文字列に一致すると判定する。

 インタフェース PatternElement は,パターン要素を表す。メソッド matches は, このパターン要素が,引数で与えられた文字列 str の位置 index から一致するかどうかを調べ, 一致すれば true を,それ以外は false を返す。ただし, index の値は0以上であるものとする。 メソッド length は,このパターン要素に一致する文字列の長さを返す。

 インタフェース PatternElement を実装した各クラスを次に示す。

(1) クラス OneChar は,通常文字1文字を表すパターン要素である。

(2) クラス AnyChar は,任意の1文字を表すパターン要素である。

(3) クラス BeginningOfString 及び EndOfString は,それぞれ文字列の先頭及び 文字列の末尾を表すパターン要素である。

 クラス Pattern は,コンストラクタで与えられたパターンをパターン要素のリストに変換する。 メソッド matches は,与えられた文字列とパターン要素のリストを照合し, 一致すれば true を,それ以外は false を返す。メソッド main はクラス Pattern のテストを行う。 メソッド main を実行すると,図1のような出力結果が得られる。

"ho.e$" matches "home'.
"ho.e$" matches "shore".
"ho.e$" doesn't match "hotel".

     図1 出力結果

 なお,このプログラムでは,1文字が char で表現できるものとし, Unicode の補助文字は考えないものとする。

〔プログラム1〕

public interface PatternElement {
   public boolean matches(String str, int index);
   public int length();
}

〔プログラム2〕

class OneChar implements PatternElement {
   private final char ch;
   OneChar(char ch) { this.ch = ch; }
   // 与えられた文字列 str の位置 index の文字とこのパターン要素が
   // 表す1文字が一致すれば true を,それ以外は false を返す。
   public boolean matches(String str, int index) {
      return str.length() > index &&  ;
   }
   public int length() { return 1; }
}

〔プログラム3〕

class AnyChar implements PatternElement {
   // 与えられた文字列 str に,位置 index から文字が一つ以上あれば true を,
   // それ以外は false を返す。
   public boolean matches(String str, int index) {
      return  ;
   }
   public int length() { return 1; }
}
〔プログラム4〕
class BeginningOfString implements PatternElement {
   public boolean matches(String str, int index) {
      return index == 0;
   }
   public int length() { return 0; }
}

〔プログラム5〕

class EndOfString implements PatternElement {
   public boolean matches(String str, int index) {
      return index == str.length();
   }
   public int length() { return 0; }
}

〔プログラム6〕

import java.util.ArrayList;
import java.util.List;

public class Pattern {
   private List<PatternElement> expr;
   public Pattern(String pattern) {
      expr = compile(pattern);
   }

   public boolean matches(String str) {
      for (int i = 0; i <= str.length(); i++) {
         if (matches(str, i))
            return true;
      }
      return false;
   }

   private boolean matches(String str, int index) {
      for (PatternElement node : expr) {
         if (!node.matches(str, index))
            return false;
         index += node.length();
      }
      return true;
   }

   private List<PatternElement> compile(String pattern) {
      List<PatternElement> list = new ArrayList<PatternElement>();
      for (int i = 0; i < pattern.length(); i++) {
         char c = pattern.charAt(i);
         PatternElement node = null;
         if (C == '.') {
            node = new ;
         } else if (c == '^') {  
            node = new BeginningOfString();
         } else if (c == '$') {
            node = new EndOfString();
         } else {
            node = new ;
         }
         list.add(node);
      }
      return list;
   }

   public static void main(String[] args) {
      String[] data = { "home", "shore", "hotel" };
      Pattern pattern = new Pattern("ho.e$");
      for (String str : data) {
         String result;
         if (  ) {
            result = "matches";
         } else {
            result = "doesn't match";
         }
         System.out.printf("\"ho.e$\" %s \"%s\".%n",
                           result, str);
      }
   }
}
設問1 プログラム中の に入れる正しい答えを, 解答群の中から選べ。

a に関する解答群

ア str.charAt(index) != ch    イ str.charAt(index) < ch

ウ str.charAt(index) == ch    エ str.charAt(index) > ch

b に関する解答群 ア str.length() < index      イ str.length() <= index

ウ str.length() > index      エ str.length() >= index

c,d に関する解答群 ア AnyChar('.')      イ AnyChar()      ウ AnyChar(c)

エ AnyChar(i)       オ OneChar('.')     力 Onechar()

キ OneChar(c)       ク OneChar(i)

e に関する解答群 ア !pattern.equals(str)    イ !pattern.matches(str)

ウ pattern.equals(str)     エ pattern.matches(str)

解答 a ←クリックすると正解が表示されます

解答 b ←クリックすると正解が表示されます

解答 c ←クリックすると正解が表示されます

解答 d ←クリックすると正解が表示されます

解答 e ←クリックすると正解が表示されます

基本情報技術者試験


設問2 プログラム6のαの行を図2のとおりに変更したとき, プログラムの動作はどうなるか。適切な記述を,解答群の中から選べ。

     } else if (c == '^' && i == 0) {    

   図2 プログラム6のαの行の変更内容

解答群 ア 文字'^'は,常に通常文字として扱われる。

イ 文字'^'は,引数 pattern の先頭にあるときだけメタ文字として扱われ, それ以外のときは,通常文字として扱われる。

ウ 文字'^'は,引数 pattern の先頭にあるときだけメタ文字として扱われ, それ以外のときは,無視される。

エ 文字'^'は,引数 pattern の先頭にあるときだけメタ文字として扱われ, それ以外のときは,例外が発生する。

解答 ←クリックすると正解が表示されます

[←前の問題] [次の問題→] [問題一覧表] [分野別] [基本情報技術者試験TOP ]