summer_tree_home

Check iOでPython3をマスターするぜっ

Verify anagrams (Scientific Expedition) - アナグラム判定

またも新しい問題が追加されていた。ますます全問クリアが遠ざかる・・・(^^;

どんな問題?

Verify anagrams
http://www.checkio.org/mission/verify-anagrams/

2つの文字列がアナグラムかどうかを判定せよ。
大文字小文字は区別しない。またスペースは除くこと。

アナグラムとは、文字を入れ換えて別の言葉にすること。文字の数が増減したり、新たな文字を加えてはいけない。
「ABC」なら

  • 「BCA」、「CBA」、「A CB」、「acb」はOK
  • 「CABC」、「ADC」、「AB」はNG

引数は、2つの文字列。
戻り値は、アナグラムかどうかのbool値を返す。

例題:

verify_anagrams("Programming", "Gram Ring Mop") == True
verify_anagrams("Hello", "Ole Oh") == False
verify_anagrams("Kyoto", "Tokyo") == True

どうやって解く?

なんか、Pythonにこういう要素の数をカウントするクラスがあったような・・・。
itertoolsだっけ?functoolsだっけ?とドキュメントを探してたら、collections.Counterだった。
これを使えば簡単だ。Counterはdictのサブクラスなので、==で比較できるはず。

from collections import Counter
 
def verify_anagrams(first_word, second_word):
    def get_counter(s):
        return Counter(s.upper().replace(' ', ''))
 
    return get_counter(first_word) == get_counter(second_word)

http://www.checkio.org/mission/verify-anagrams/publications/natsuki/python-3/counter/


dictの場合、==はオブジェクトの比較じゃなくて全要素の比較だったと思うのだが、ちょっと不安になってドキュメントを調べてみた。

同じ型のオブジェクト間における比較は、型によって異なります:

  • マッピング (辞書) は、同じ (key, value) の対を持つときのみ等しくなります。

http://docs.python.jp/3.3/reference/expressions.html?highlight=%E6%AF%94%E8%BC%83#not-in

問題ないみたい。

オブジェクトが同じ(参照が同じ)かどうかを調べるときは、is を使えばいいようだ。

>>> dic1 = {'a': 1, 'b': 2, 'c': 3}
>>> dic2 = {'c': 3, 'a': 1, 'b': 2}
>>> dic1 == dic2  # 内容の比較
True
>>> dic1 is dic2  # 参照の比較
False