例として組み合わせ論からのタスクを使用したPythonの表現力のシンプルさ

自己学習の過程で、Pythonプログラミング言語(c / c ++の知識を持っている)は、関数ジョブとしてさまざまな組み合わせ構成のセットから生成関数を記述することにしました。 もちろん、そのような機能は既にitertoolsモジュールの標準pythonライブラリに含まれていることに気付くことができますが、誰でも自転車を発明する権利を持っている必要があります。特にトレーニング目的で...

確率論の基礎に精通している人は、骨n計画とは何か、この表が何であるかを覚えておく必要があります。





そして、TK-一意の文字とサンプルサイズkで構成される文字列sを取得して文字列を返す4つのジェネレーターを作成します。文字列sの順序からk文字を繰り返す/使用しないサンプルは重要です。

結果は次のコードです。



import itertools from functools import partial import unittest def template(s, k, assertion, reducer): n = len(s) assert assertion(n, k) if k == 0: yield "" elif k == 1: for c in s: yield c else: k-=1 for i, c in enumerate(s): new_s = reducer(s, i) if not assertion(len(new_s), k): break for res in template(new_s, k, assertion, reducer): yield c+res assertion_norep = lambda n, k: n > 0 and n >= k and k >= 0 assertion_rep = lambda n, k: n > 0 and k >= 0 permutation_norep = partial(template, assertion=assertion_norep, reducer=lambda s, i: s[:i]+s[i+1:]) permutation_rep = partial(template, assertion=assertion_rep, reducer=lambda s, i: s) combination_norep = partial(template, assertion=assertion_norep, reducer=lambda s, i: s[i+1:]) combination_rep = partial(template, assertion=assertion_rep, reducer=lambda s, i: s[i:]) class TestCombinatoricGenerators(unittest.TestCase): @classmethod def setUpClass(cls): cls.test_string = "abcdefg" cls.k = 5 def test_permutation_norep(self): self.assertEquals(set(permutation_norep(self.test_string, self.k)), set(map(''.join, itertools.permutations(self.test_string, self.k)))) def test_permutation_rep(self): self.assertEquals(set(permutation_rep(self.test_string, self.k)), set(map(''.join, itertools.product(self.test_string, repeat=self.k)))) def test_combination_norep(self): self.assertEquals(set(combination_norep(self.test_string, self.k)), set(map(''.join, itertools.combinations(self.test_string, self.k)))) def test_combination_rep(self): self.assertEquals(set(combination_rep(self.test_string, self.k)), set(map(''.join, itertools.combinations_with_replacement(self.test_string, self.k)))) if __name__ == '__main__': unittest.main()
      
      







pythonはc / c ++よりもさらに高い抽象化レベルの言語であるため、他の言語ではよりかさばり、混乱を招くコードを書くのが簡単で表現力豊かになります。 Pythonの初心者には、いくつかの点に注意を引きたいと思います。



  • 利回り後に戻る
  • 再帰ジェネレーター
  • 戦略テンプレート
  • ラムダ関数を使用する




PS

私は、一般的な「テンプレート」機能を使用して、すぐに同様のソリューションに至らなかったことを付け加えることができます。 最初にすべての関数を別々に作成し、次に一般的なものと異なるものを強調しました。



All Articles