LoginSignup
1
3

More than 3 years have passed since last update.

Python未経験者が言語処理100本ノックをやってみる00~04

Last updated at Posted at 2020-03-18

[追記]
05~06はこちら
Python未経験者が言語処理100本ノックをやってみる05~06
https://qiita.com/earlgrey914/items/e772f1b7e5efea114e1d
07~09はこちら
Python未経験者が言語処理100本ノックをやってみる07~09
https://qiita.com/earlgrey914/items/a7b6781037bc0844744b


やってみるのはこちら

<言語処理100本ノック 2015>
https://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/245698

筆者プロフ(重要)
Pythonの基礎学習経験は皆無。
ネットに転がっているサンプルをコピペして動かせるレベル。
Javaを大学の演習で少し触ったことがある。
現職はプログラマーではない。

(重要)この記事は、正しく美しい答えを書くのではなく、上記レベルの人間がどうやったら答えにたどり着いたかの過程を記録していく。

00. 文字列の逆順

文字列"stressed"の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.

「Python 文字列 反転」でググってヒットしたページに回答があった。
https://qiita.com/Hawk84/items/ecd0c7239e490ea22308

enshu0.py
str = "stressed"
str = str[::-1]
print(str)
dessert

[::-1]がどういう意味なのかわからん。

~5分ググった~
どうやらpythonにはスライスという、文字列やらリストやらを切り取ったりなんたらしてくれる機能があるらしい。
[0:3]と書けば文字列の1番目(0)から3番目(3)までの3文字を返してくれるらしい。
ここめっちゃわかりづらいな。
普通0から始まって3まで数えたら0,1,2,3の4文字を返してくれると思わない?(愚痴)

で、

先頭から末尾までを指定したい場合[:]と書けばよいらしい。
スライスは[ここから:ここまで]という記法だが、先頭と末尾の場合の場合は省略できるので[:]と書ける。

で、

最後に[-1]をつけると文字列を反転して返してくれるらしい。
なので[::-1]と書くと先頭から末尾までを反転して返してくれる。

<参考URL>
https://www.sejuku.net/blog/44850

01. 「パタトクカシーー」

「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.

enshu01.py
str = "パタトクカシーー"
str = str[::2]
print(str)
パトカー

さっきスライスについてググっていたので、これもスライスを使えばいけそうであることがすぐわかった。
[::2]の記載は、[先頭から:末尾まで:最初の文字番号を1として、最初の文字+2ずつしした文字を切り取り]という意味らしい。
なので先頭から末尾までの1,3,5,7文字目が取り出せる。
「タクシー」を取り出したいなら最初の文字をタにすればいいので以下でOK。

enshu01_2.py
str = "パタトクカシーー"
str = str[1::2]
print(str)
タクシー

これは[2番目の文字(1)から:末尾まで:最初の文字番号を1として、最初の文字+2ずつしした文字を切り取り]という意味になる。

02. 「パトカー」+「タクシー」=「パタトクカシーー」

「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.

もうつまづいた。
Javaの知識だとこういうfor文を書けばいけるのだが、そんなのでいいのだろうか。

dousshiyou.java
String patoka = "パトカー";
String takushi = "タクシー";
int n = patoka.length();

String answer = "";

for (int i = 0; i < n; i++){
 answer = answer + パトカーを1文字ずつスライスしたi番目の文字
 answer = answer + タクシーを1文字ずつスライスしたi番目の文字
}

多分ダメだろう・・・てかPythonでfor (int i = 0; i < n; i++) みたいなfor文書けるのか知らん。
出題者はおそらく異なる回答をもっている。
(このjavaの書き方は脳内イメージを文字に起こしただけなので記法などについてはツッコまないでいただきたい)

~10分ほどググった~
結果、良い答えがわからなかった。
適当にfor文を書いていたら以下の発見があった

tekitou.py
str_p = "パトカー"

for i in str_p:
    print(i)
パ
ト
カ
ー

なにやら1文字ずつ出力されているぞ?

あとzip()というものを使うと2つのリストを同時に処理できるらしい
<参考>
https://uxmilk.jp/13726

じゃあこれでいいのだろうか。

enshu02.py
str_p = "パトカー"
str_t = "タクシー"
answer = ""

for p,t in zip(str_p,str_t):
    answer = answer + p
    answer = answer + t

print(answer)
パタトクカシーー

どうなんだろう。まぁ一応できたけども。
答え合わせはまだ後で・・・

03. 円周率

"Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.

これは簡単そうだ。
split()で文字列を任意文字で区切ってリスト化できるのは知ってるぞ。

lisitka.py
str = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
list = str.split()
print(list)
['Now', 'I', 'need', 'a', 'drink,', 'alcoholic', 'of', 'course,', 'after', 'the', 'heavy', 'lectures', 'involving', 'quantum', 'mechanics.']

じゃああとはリスト内の文字列の長さを取得すればよい。

koredeiinoka.py
s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
list = s.split()

answer = ""

for i in list:
    answer = answer + str(len(i))

print(answer)
3141692753589710

今回、文字列を格納してる変数にstrという名称をつけるのをやめた。
数値から文字列に変換するときにstr()を使うことを知ったのだが、これとかぶるから。
ついでにanswer = answer + str(len(i))っていう文字列結合のやり方がダサいからヤメたい・・・

で、解答として合ってるかというと
なんか・・・色々と違くね?

「リストを作成せよ」って出題なのに文字列で返してるし、
3.141592・・・・じゃないね。3.141692になっている。
どうやら最初のリストで、カンマは削除してあげなければならないようだ。
↓カンマが入ってしまっている。

['Now', 'I', 'need', 'a', 'drink,', 'alcoholic', 'of', 'course,', 'after', 'the', 'heavy', 'lectures', 'involving', 'quantum', 'mechanics.']

とりあえずreplace(",","")でカンマを除去する
<参考URL>
http://python-remrin.hatenadiary.jp/entry/2017/04/24/174405

jokyo.py
s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
s = s.replace(",","")
print(s)
Now I need a drink alcoholic of course after the heavy lectures involving quantum mechanics.

これ末尾のピリオドも除去したほうがいいのかしら?
だとしたらreplaceを2回。

datoshitara.py
s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
s = s.replace(",", "").replace(".", "")
print(s)
Now I need a drink alcoholic of course after the heavy lectures involving quantum mechanics

よし、これでいいだろう。

enshu03.py
s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."
s = s.replace(",", "").replace(".", "")

list = s.split()
#['Now', 'I', 'need', 'a', 'drink', 'alcoholic', 'of', 'course', 'after', 'the', 'heavy', 'lectures', 'involving', 'quantum', 'mechanics']

answer_list = []
for i in list:
    answer_list.append(len(i))
print(answer_list)
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]

いえーい。

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文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

やべぇすでに何言ってるのかわかんねぇ。
単語に分解はsplit()でいいだろう。
文字取り出しも多分スライスでいけるだろう。

取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.

これが何言ってるのかわかんねぇ。

~3分ほどググった~
<参考URL>
https://web-camp.io/magazine/archives/14815

あーはーん。
Key-Value Store的なやつね。なるほど完全に理解した()
よくわからんけど↓こうなってればええんやろ。

{key1:value1,key2:value2,key3:value3}

だから解答的には

{1:H,2:He,3:Li,4:Be,5:B,・・・}

みたいになってればええんやな。

enshu04.py
s = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."

#単語で分割
list = s.split()

#この単語の出現番号がこのリストの番号と一致してたら1文字だけ返すリスト
ichimoziList = [1, 5, 6, 7, 8, 9, 15, 16, 19]

#辞書型
dic = {}

counter = 1
for i in list:
    if counter in ichimoziList:
        dic[counter] = i[:1]
    else:
        dic[counter] = i[:2]
    counter+= 1

print(dic)
{1: 'H', 2: 'He', 3: 'Li', 4: 'Be', 5: 'B', 6: 'C', 7: 'N', 8: 'O', 9: 'F', 10: 'Ne', 11: 'Na', 12: 'Mi', 13: 'Al', 14: 'Si', 15: 'P', 16: 'S', 17: 'Cl', 18: 'Ar', 19: 'K', 20: 'Ca'}

いえい!!できちまったぜ。
思ったんだけど辞書型ってこの{1:'H',・・・}の順で使うので合ってるの?
こうなのかしら・・・{'H':1,・・・}
どっちでもいいのかしら(鼻ホジー

こちらではif文が初登場。
1,5,6,7,8,9,15,16,19のリストを作って、処理する単語の順番の数値がリストにふくまれていたら~っていう
条件分岐を書きました。

Pythonのfor文の使い方に慣れていないのでcounterを外だししているんだけど、
もう少しスッキリできるかもね。

あと「繰り返し処理内で1ずつ足す」はcounter++ ではなくcounter += !って書くらしい。へ~。

長くなったので続きは別記事で!!!
ここまで3時間かかりました!!!!!!!!!!!(重要)

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3