この質問をCode Review -areaに移動してください。私は以下のコードが迷惑であることを知っており、重要なフィードバックを書き換えを完了させたいからです。私は車輪をかなり改革しています。より良い構造のfor-if messesを簡略化しますか?
# Description: you are given a bitwise pattern and a string
# you need to find the number of times the pattern matches in the string.
# The pattern is determined by markov chain.
# For simplicity, suppose the ones and zeros as unbiased coin flipping
# that stops as it hits the pattern, below.
#
# Any one liner or simple pythonic solution?
import random
def matchIt(yourString, yourPattern):
"""find the number of times yourPattern occurs in yourString"""
count = 0
matchTimes = 0
# How can you simplify the for-if structures?
# THIS IS AN EXAMPLE HOW NOT TO DO IT, hence Code-Smell-label
# please, read clarifications in [Update]
for coin in yourString:
#return to base
if count == len(pattern):
matchTimes = matchTimes + 1
count = 0
#special case to return to 2, there could be more this type of conditions
#so this type of if-conditionals are screaming for a havoc
if count == 2 and pattern[count] == 1:
count = count - 1
#the work horse
#it could be simpler by breaking the intial string of lenght 'l'
#to blocks of pattern-length, the number of them is 'l - len(pattern)-1'
if coin == pattern[count]:
count=count+1
average = len(yourString)/matchTimes
return [average, matchTimes]
# Generates the list
myString =[]
for x in range(10000):
myString= myString + [int(random.random()*2)]
pattern = [1,0,0]
result = matchIt(myString, pattern)
print("The sample had "+str(result[1])+" matches and its size was "+str(len(myString))+".\n" +
"So it took "+str(result[0])+" steps in average.\n" +
"RESULT: "+str([a for a in "FAILURE" if result[0] != 8]))
# Sample Output
#
# The sample had 1656 matches and its size was 10000.
# So it took 6 steps in average.
# RESULT: ['F', 'A', 'I', 'L', 'U', 'R', 'E']
[更新]
私は多分、問題はその方法を簡略化することができ、ここでの理論について少し説明します。上記のコードは、下記の遷移行列A
でマルコフ連鎖を構築しようとしています。あなたがコインフリッピングとして想像できるパターン100
はそれに対応しています。当該
>>> Q=numpy.matrix('0.5 0.5 0; 0 0.5 0.5; 0 0.5 0')
>>> I=numpy.identity(3)
>>> I
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> Q
matrix([[ 0.5, 0.5, 0. ],
[ 0. , 0.5, 0.5],
[ 0. , 0.5, 0. ]])
>>> A=numpy.matrix('0.5 0.5 0 0; 0 0.5 0.5 0; 0 0.5 0 0.5; 0 0 0 1')
>>> A
matrix([[ 0.5, 0.5, 0. , 0. ],
[ 0. , 0.5, 0.5, 0. ],
[ 0. , 0.5, 0. , 0.5],
[ 0. , 0. , 0. , 1. ]])
average
8
マトリックス上記Q
N=(I-Q)^-1
内の最初の行に値の和となります。
>>> (I-Q)**-1
matrix([[ 2., 4., 2.],
[ 0., 4., 2.],
[ 0., 2., 2.]])
>>> numpy.sum(((I-Q)**-1)[0])
8.0
ここで、この見かけ上のみのパターンマッチング問題がマルコフチェーンになることがわかります。あなたは乱雑なfor-if-if条件を行列や行列に似たものに置き換えることができなかった理由はわかりません。私はそれらを実装する方法はわかりませんが、繰り返しを行う必要がある州が増えれば、イテレータは研究の道を開くことができます。
しかし、Numpyに問題が発生しました。-Inf
とNaN
は何ですか?上の数値が(I-Q)**-1
の行列から収束する値を確認します。 N
はN=I+Q+Q^2+Q^3+...=\frac{I-Q^{n}}{I-Q}
です。
>>> (I-Q**99)/(I-Q)
matrix([[ 2.00000000e+00, 1.80853571e-09, -Inf],
[ NaN, 2.00000000e+00, 6.90799171e-10],
[ NaN, 6.90799171e-10, 1.00000000e+00]])
>>> (I-Q**10)/(I-Q)
matrix([[ 1.99804688, 0.27929688, -Inf],
[ NaN, 1.82617188, 0.10742188],
[ NaN, 0.10742188, 0.96679688]])
これは宿題か面接の割り当てですか?その場合は、宿題としてタグ付けしてください。 – gotgenes
また、三重引用符で囲まれた文字列をコメントとして使用することは残念です。本当のコメントでなければなりません(プレフィックス '#')。 – gotgenes
gotgenes:いいえ、私は数学以外の何かをしています。この問題は、より良い構造で殺される可能性があります。 – hhh