私はそれを理解したので、私はこの答えを書いていますので、私にご負担ください。
あなたが述べたように、大きなp
ためb[p]
を生成するよりも、b[p][q]
の文字が元x
文字の中から来ている場所を見つけるためにはるかに簡単です。これを行うには、ループを使用して現在のb[p][q]
がどこから来たのかを調べ、1
とx
の間になるまでp
を減らし、1
までq
になるまで減らします。
私たちが式を得ることができるかどうかx=3
を見るの例を見てみましょう:
p N(p) b[p]
- ---- ----
1 1 a
2 1 b
3 1 c
4 3 a b c
5 5 b c abc
6 9 c abc bcabc
7 17 abc bcabc cabcbcabc
8 31 bcabc cabcbcabc abcbcabccabcbcabc
9 57 cabcbcabc abcbcabccabcbcabc bcabccabcbcabcabcbcabccabcbcabc
シーケンスは明確である:N(p) = N(p-1) + N(p-2) + N(p-3)
、N(p)
はb
のp番目の要素内の文字の数です。p
とx
が与えられた場合は、[1, p]
の範囲のすべてのN
をブルートフォースで計算できます。これにより、b
b[p][q]
のどの先行要素が由来したのかを知ることができます。
たとえば、x=3
,p=9
およびq=45
とします。
- チャートは、上記
N(6)=9
、N(7)=17
とN(8)=31
を与えます。 45>9+17
以降、b[9][45]
はb[8][45-(9+17)] = b[8][19]
に由来することがわかります。
- 繰り返し/反復的に、
19>9+5
のように、b[8][19] = b[7][19-(9+5)] = b[7][5]
。
- 今や
5>N(4)
でも5<N(4)+N(5)
なので、b[7][5] = b[5][5-3] = b[5][2]
です。 3 <= x
以来
b[5][2] = b[3][2-1] = b[3][1]
- 、我々は我々の終了条件を持っている、と
b[9][45]
はb[3]
からc
です。
このような何かを非常に簡単にx
までp
、q
、x
とb
を開始与えられたいずれかの再帰的または反復的に計算することができます。私の方法では配列全体に対してN(p)
を計算するにはp
配列要素が必要です。これは、再帰的に動作している場合、配列またはスタックに割り当てることができます。 (numpyのはおそらくこれを合理化に役立つだろうが、外付けの輸入、)ここで
はバニラPythonでリファレンス実装です:
def so38509640(b, p, q):
"""
p, q are integers. b is a char sequence of length x.
list, string, or tuple are all valid choices for b.
"""
x = len(b)
# Trivial case
if p <= x:
if q != 1:
raise ValueError('q={} out of bounds for p={}'.format(q, p))
return p, b[p - 1]
# Construct list of counts
N = [1] * p
for i in range(x, p):
N[i] = sum(N[i - x:i])
print('N =', N)
# Error check
if q > N[-1]:
raise ValueError('q={} out of bounds for p={}'.format(q, p))
print('b[{}][{}]'.format(p, q), end='')
# Reduce p, q until it is p < x
while p > x:
# Find which previous element character q comes from
offset = 0
for i in range(p - x - 1, p):
if i == p - 1:
raise ValueError('q={} out of bounds for p={}'.format(q, p))
if offset + N[i] >= q:
q -= offset
p = i + 1
print(' = b[{}][{}]'.format(p, q), end='')
break
offset += N[i]
print()
return p, b[p - 1]
so38509640('abc', 9, 45)
を呼び出すことで、たとえば、
同様
N = [1, 1, 1, 3, 5, 9, 17, 31, 57]
b[9][45] = b[8][19] = b[7][5] = b[5][2] = b[3][1]
(3, 'c') # <-- Final answer
を生成します質問so38509640('abc', 7, 5)
は、予想される結果を生成します。
N = [1, 1, 1, 3, 5, 9, 17]
b[7][5] = b[5][2] = b[3][1]
(3, 'c') # <-- Final answer
申し訳ありませんより良い関数名を思いつくことができません:)これは、関数/クラスrange
の違いにもかかわらず、Py2と3で同じようにうまくいくはずのシンプルなコードです。
この問題の非反復的な解決策があるかどうかは非常に興味があります。おそらく、モジュラ算術または何かを使用してこれを行う方法があります。
x = 3、b = a、b、c、a b c、b c abc、c abc bcabc、abc bcabc cabcbcabcなど? (スペースを分かりやすくするために、コンマは配列要素を分けているだけです) –
@Mad Physicistが書いたものは正しいものです。今、p = 7、q = 5のクエリがある場合、私の答えはcまたは3番目の文字でなければなりません。 –
ヒント:要素の長さは、高次フィボナッチ配列です。まず、q
lorro