基本情報ではじめる Python 最終回 試験問題レベルにチャレンジ
error
この記事は基本情報技術者試験の旧制度( 2022 年以前)の記事です。
この記事の題材となっている「午後問題」は現在の試験制度では出題されません。 ご注意くださいませ。
この連載では、プログラミングの入門者を対象として、基本情報技術者試験の出題範囲にテーマを絞って、 Python の言語構文とプログラムの読み方を説明します。
前回までで、試験の出題範囲をほぼ網羅して学習できました。最終回となる今回は、総仕上げとして、試験問題レベルの Python のプログラムにチャレンジしてみましょう。
問題
次の Python プログラムの説明及びプログラムを読んで、設問に答えよ。
〔問題〕
文字列の中から、回文( palindrome )を探して表示する関数 find_palindrome である。回文とは、先頭から読んだ文字の並びと末尾から読んだ文字の並びが一致する文字の並びのことである。ただし、ここでは次の条件を満たすものとする。
- 文字列は英字( A ~ Z、 a ~ z )、数字( 0 ~ 9 )、記号( !”#%&'()*+、-./:+<=>?[]^_{|} )及び空白文字から成る。
- 文字の並びを読むとき、英字の大文字と小文字は区別しない。
- 文字の並びを読むとき、記号及び空白文字は無視する。
- 回文は英数字で始まり英数字で終わる。ただし、英数字 1 文字は回文ではない。
本問のプログラムが表示する回文の例を表 1 に示す。 No.1 で示す文字列において、文字の並び bc0cb は回文である。 c0c も回文であるが、本問のプログラムでは、文字列の先頭に最も近い文字から始まるものを表示する。また、 No.2 で示す文字列において、英字の大文字と小文字は区別しないので、文字の並び Bc0Cb は回文である。さらに、 No.3 で示す文字列において、英字の大文字と小文字を区別せず、かつ、記号及び空白文字を無視するので、文字の並び B!c0Cb は回文である。 No.4 で示す文字列において、文字列の先頭に最も近い b を先頭文字とする文字の並び bc0cb と bc0cb1bc0cb は、いずれも回文である。しかし、本問のプログラムでは、先頭文字位置が同じ回文が複数あれば、長さが最も短いものを表示する。
No. | 文字列 | 表示する回文 |
---|---|---|
1 | abc0cbe | bc0cb |
2 | ABc0CbE | Bc0Cb |
3 | AB!c0 CbE | B!c0 Cb |
4 | abc0cb1bc0cbe | bc0cb |
- 関数 find_palindrome の仕様は、次のとおりである。ここで、引数の値に誤りはないものとする。
- 機能
- 文字列 text の中から、回文を探して表示する。文字列 text の中に複数の回文がある場合、先頭文字位置が文字列の先頭に最も近いものを表示する。さらに、先頭文字位置が同じ回文が複数あれば、長さが最も短いものを表示する。
- 引数
- text 文字列
関数 find_palindrome は、関数 is_palindrome 及び関数 find_char を使用する。
- 関数 is_palindrome の仕様は、次のとおりである。ここで、引数の値に誤りはないものとする。
- 機能
- 文字の並び chars の idx 以降が回文かどうかを判定する。
- 引数
- chars 文字の並び
- idx チェックする先頭位置の添え字
- size チェックする文字数
- 返却値
- 回文の場合は 1
- 回文でない場合は 0
- 関数find_charの仕様は、次のとおりである。ここで、引数の値に誤りはないものとする。
- 機能
- 文字列 st の idx 以降で、文字 ch が最初に現れる位置を求める。ただし、英字の大文字と小文字は区別しない。
- 引数
- st 文字列
- idx チェックする先頭位置の添え字
- ch 文字
- 返却値
- 文字 ch が現れる場合は、それが最初に現れる位置の添え字
- 文字 ch が現れない場合は、 -1
- プログラム中で使用している組み込み関数やメソッドの概要は、次のとおりである。
- s.isalnum()
- 文字列sの内容がすべて英数字のとき、Trueを返し、それ以外のとき、Falseを返す。
- s.lower()
- 文字列sの中にあるすべての英大文字を、英小文字に変換した文字列を返す。
- print(s, end = “”)
- 文字列sを表示して、改行しない。
〔プログラム〕
def find_palindrome(text):
for i in range(len(text)):
if not text[i].isalnum():
continue
# ithは、文字列textの第i文字の添え字
ith = i
# hitは、第i文字と一致した文字の添え字
hit = find_char(text, ith + 1, text[ith])
while hit != -1:
# psizeは、文字の並びの長さ
psize = "[ a ]"
if is_palindrome(text, ith, psize):
while ith < hit + 1:
print(text[ith], end = "")
ith += 1
print()
return
hit = find_char(text, hit + 1, text[ith])
def is_palindrome(chars, idx, size):
l = idx
r = idx + size - 1
while l < r:
while not chars[l].isalnum():
l += 1
while not chars[r].isalnum():
r -= 1
if "[ b ]":
return 0
l += 1
r -= 1
return 1
def find_char(st, idx, ch):
for i in range(idx, len(st)):
if "[ c ]":
return i
return -1
設問
プログラム中の[ ]に入れる正しい答えを、解答群の中から選べ。
a に関する解答群
ア i
イ ith
ウ ith + 1
エ hit - ith
オ hit - ith + 1
b に関する解答群
ア l == r
イ 1 != r
ウ chars[l] == chars[r]
エ chars[l] != chars[r]
オ chars[l].lower() == chars[r].lower()
カ chars[l].lower() != chars[r].lower()
c に関する解答群
ア ch == st[i]
イ ch != st[i]
ウ ch.lower() == st[i].lower()
エ ch.lower() != st[i].lower()
オ (ch == st[i].lower()) or (ch.lower() == st[i])
カ (ch == st[i].lower()) and (ch.lower() == st[i])
解答と解説
空欄 a の解説
表 1 に示された「 abc0cbe 」という文字列から「 bc0cb 」という回文が表示される例を想定して、関数 find_palindrome の処理の流れを追いかけてみましょう。
- 6 行目で、「 abc0cbe 」の先頭の「 a 」の添え字が変数 ith に格納されます。
- 8 行目で、「 abc0cbe 」の先頭から 1 つ先を起点とした「 bc0cbe 」という文字列から先頭の「 a 」と、同じ文字があるかどうかが関数 find_char で検索されます。
この場合は、見つからないので、関数 find_char の戻り値は -1 になり、それ以降にある while 文の処理は行われず、次の文字の処理に進みます。 - 6 行目で、「 abc0cbe 」の 2 文字目の「 b 」の添え字が変数 ith に格納されます。
- 8 行目で、「 abc0cbe 」の 2 文字目から 1 つ先を起点とした「 c0cbe 」という文字列から 2 文字目の「 b 」と、同じ文字があるかどうかが関数 find_char で検索されます。この場合は、「 b 」が見つかり、関数 find_char の戻り値は見つかった「 b 」の位置の添え字になり、それ以降の while 文の処理に入ります。
- 11 行目で変数 psize に空欄 a の値を代入します。
- 12 行目で変数 psize を関数 is_palindrome の第 3 引数に指定しています。関数の仕様を見ると、第 3 引数は、チェックする文字数です。
ここでは、「 abc0cbe 」の「 bc0cb 」という文字の並びが回文かどうかをチェックします。
この文字の並びの長さは、「 bc0cb 」の先頭の「 b 」を指す添え字 ith と、末尾の「 b 」を指す添え字 hit の差、プラス 1 で求められます。したがって、空欄 a は、hit - ith + 1
(選択肢オ)です。
空欄 b の解説
関数 is_palindrome では、文字列 chars を左端からたどる l と右端からたどる r を 1 つずつ変化させる while 文で、文字列 chars が回文かどうかをチェックしています。
左端からたどった文字はchars[l]
であり、右端からたどった文字はchars[r]
です。
空欄 b には、関数 is_palindrome が戻り値として 0 を返す条件が入ります。関数 is_palindrome の仕様を見ると、戻り値として 0 を返すのは、文字列 chars が回文でない場合です。
大文字と小文字が違っても同じとみなすので、空欄 b の条件は、小文字に統一して等しくないことをチェックするchars[l].lower() != chars[r].lower()
(選択肢カ)です。
空欄 c の解説
関数 find_char は、引数で指定された文字列 st から文字 ch を見つけて、最初に見つかった位置の添え字を返します。
空欄 c は、st[i]
の添え字を返す処理の条件です。大文字と小文字が違っても同じとみなすので、ch.lower() == st[i].lower()
(選択肢ウ)です。
空欄 a ― オ
空欄 b ― カ
空欄 c ― ウ
いかがでしたか。 Python のプログラムを読み取って、問題を解けましたか?
もしも、プログラミングの学習を始めたばかりなら、スラスラできなくても当然です。同じ問題を、何度も繰り返し練習してください。時間はかかるかもしれませんが、必ずできるようになります。
この連載は、今回で最終回になります。これまで連載をお読みいただいた皆様に、この場をお借りして、厚く御礼申し上げます。
またどこかでお会いしましょう!
label 関連タグ
免除試験を受けた 74.9% の方が、 科目A免除資格を得ています。
基本情報ではじめる Python 最終回 試験問題レベルにチャレンジ
update基本情報ではじめる Python (9) import 文とライブラリの活用
update基本情報ではじめる Python (8) 組み込み関数
update基本情報ではじめる Python (7) generator と yield 文
update基本情報ではじめる Python (6) ラムダ式 って何? どんな用途で使うの?
update基本情報ではじめる Python (5) オブジェクト指向
update基本情報ではじめる Python (4) if ~ else と while / for
update基本情報ではじめる Python (3) 引数 ~ Python の関数の引数には様々な形式がある
update基本情報ではじめる Python (2) 配列 ~ リスト、タプル、文字列、集合、辞書の特徴
update基本情報ではじめる Python (1) 基本構文 ~ 擬似言語と比べて覚える
update『プログラムはなぜ動くのか』(日経BP)が大ベストセラー
IT技術を楽しく・分かりやすく教える“自称ソフトウェア芸人”
大手電気メーカーでPCの製造、ソフトハウスでプログラマを経験。独立後、現在はアプリケーションの開発と販売に従事。その傍ら、書籍・雑誌の執筆、またセミナー講師として活躍。軽快な口調で、知識0ベースのITエンジニアや一般書店フェアなどの一般的なPCユーザの講習ではダントツの評価。
お客様の満足を何よりも大切にし、わかりやすい、のせるのが上手い自称ソフトウェア芸人。
主な著作物
- 「プログラムはなぜ動くのか」(日経BP)
- 「コンピュータはなぜ動くのか」(日経BP)
- 「出るとこだけ! 基本情報技術者」 (翔泳社)
- 「ベテランが丁寧に教えてくれる ハードウェアの知識と実務」(翔泳社)
- 「ifとelseの思考術」(ソフトバンククリエイティブ) など多数