はじめに
今回は第1章の問題の前半部分No.0~No.4までを解いていきたいと思います.
第1章の問題はプログミング経験者ならすんなりと理解できる内容・レベル感です.
組み込み関数を知っているかどうかがキーポイントとなるのでここで学んでいきましょう.
では早速解いていきたいと思います.
00.文字列の逆順
文字列”stressed”の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ
コード
word = "stressed"
re_word_list = list(reversed(word))
re_word = "".join(re_word_list)
print(re_word)
出力
desserts
解説
pythonの要素を逆順に取り出す組み込み関数を使えば簡単に逆順になります.
reversed(text)で逆順になったオブジェクトをリスト型に変換し,結合することで並び替えが完成します.
01.「パタトクカシーー」
「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.
コード
word = "パタトクカシーー"
ans_list = [word[i] for i in range(1,len(word),2)]
ans = "".join(ans_list)
print(ans)
出力
タクシー
解説
文字列から特定の位置を取得してくるだけなので,text内の特定の位置を指定すれば良いです.
今回は奇数の位置を取得して来ることで対象の言葉を作ることができるのでfor文を回して要素を取得する形で実装しました.
02.「パトカー」+「タクシー」=「パタトクカシーー」
「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.
コード
word1= "パトカー"
word2= "タクシー"
ans = ""
for w1,w2 in zip(word1,word2):
ans += w1+w2
print(ans)
出力
タクシー
解説
問題では文字列の長さが一緒なので,for文で先頭から順に”パトカー”と”タクシー”の要素を取得し,正解の単語を作成する形にしました.
zip()はpythonの組み込み関数で()内のものをtuple形式のオブジェクトとして先頭から順に持って来れます.
一つ例を載せておきます.
x = [1,2,3]
y = [2,4,6]
print(list(zip(x,y)))
#出力:[(1, 2), (2, 4), (3, 6)]
03.円周率
“Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.”という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.
コード
import re
text = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
#カンマやピリオドの除去
text = re.sub("[,.]", "", text)
print(text)
word_list = text.split(" ")
n_list = [len(i) for i in word_list]
print(n_list)
出力
Now I need a drink alcoholic of course after the heavy lectures involving quantum mechanics
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
解説
各単語の長さを先頭から取得したいので,まずは,単語で区切るときに邪魔になる”,”や”.”を除去します.
除去には正規表現操作のモジュールreのre.sub()を使います.
re.sub(“削除する文字”,”削除後の処理”,”削除対象の文字列”)という形で入力します.
余計なものがなくなった出力に対して,空白区切りでテキストをリスト化します.
その後,リストの各要素の長さを取得し,出力することで円周率になっているかと思います.
下記でリストの出力と円周率が等しくなっているか確認してみましょう.
import math
print(math.pi)
#3.141592653589793
04.元素記号
“Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.”という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭の2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.
コード
text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
word_list = text.split()
one_word = [1, 5, 6, 7, 8, 9, 15, 16, 19]
ans_list = [word_list[i][0] if i+1 in one_word else word_list[i][:2] for i in range(len(word_list))]
print(ans_list)
出力
['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mi', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca']
解説
今回は要素の位置によって取得したい文字数が変わるという問題です.
単純に1文字取得か,2文字取得かの二択なので,if文で分岐させることを考えます.
03の問題と同様にテキストをsplitしてリスト化し,そのリストの要素位置によって出力が変わるようにリスト内包表記でfor文を回します.
リスト内包表記はコードの行数を抑えられることや速度が早いという特徴があります.
その一方で,処理がわかりづらいという面もあるので,今回は下記に普通にfor文で回した際のコードも記載しておきます.(特にif文が絡むとわかりづらい…)
text = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
word_list = text.split(" ")
one_word = [1, 5, 6, 7, 8, 9, 15, 16, 19]
ans_list = []
for i,word in enumerate(word_list):
if i+1 in one_word:
ans_list.append(word[0])
else:
ans_list.append(word[:2])
print(ans_list)
# ['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mi', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca']
終わりに
今回は言語処理100本ノック第1章の00~04までの問題を解きました.
pythonのfor文操作や文字列操作を知っていればあまり躓くことなく問題を解けたかと思います.
載せている解法も数行で理解しやすいと思うので,是非参考にしながらご自身でも解いてみてください.
今後も引き続き言語処理100本ノックに取り組んでいきます‼︎
コメント