私はPythonを初めて使用し、モジュロに問題があります。
コードは次のとおりです。
for i in range(ord('a'), ord('z')+1):
print chr(((i+2) % 97) + 97 )
期待される結果はcdef...a
です。ただし、に到達すると、ラップアラウンドという望ましいモジュール動作が得られませんz
。
97はラップしたいものではないので、ord('z')
= 122でラップしてから、 ord('a')
(97)の値を追加します。
あなたが本当にしなければならない完全な計算は、オフセットにシフトしてからセットに戻ることです。例えば...
for i in range(ord('z') - ord('a') + 1): # equivalent to range(26); i.e. 0-25
print chr(((i+2) % 26) + ord('a')) # results in 2+97 'c', 3+97 'd', etc.
既存のコードが機能しない理由は、i+2
常に97より大きくなるためです(i
開始ord('a')
が97で、そこから上に行くため)。したがって、% 97
は事実上ちょうど- 97
であり、したがって、印刷行は事実上次のようになります。
print chr(((i+2) - 97) + 97 )
これは...に減少します
print chr((i+2) - 97 + 97)
これは明らかにただのことprint chr(i+2)
です。
26(英語のアルファベットの文字数)を法として作業する必要があります。このコードは機能します:
for i in range(ord('a'), ord('z') + 1):
j = i - ord('a')
print chr(ord('a') + (j + 2) % 26)
このインデックス作成テンプレートを検討してください。
A + (j + B) % C
のさまざまな値をj
範囲にマップしますA … (A + C - 1)
。元々、とを選択A = 97
しC = 97
たので、範囲にマッピングしています97 … 193
。とを選択A = ord('a') = 97
したので、範囲、つまり、にC = 26
マッピングしています。97 … 122
ord('a') … ord('z')
さて、オフセットについてB
です。左に2箇所回転したかったので、正しく選択しましB = 2
た。ただし、これを機能させるには、ローテーションの前にa
最初の文字をエンコードする必要があるためです。0
したがって、j = i - ord('a')
値を0〜26の範囲に調整し、変更し、modを適用してから、正しい文字範囲に戻す必要があります。ここにそれは複数のステップにあります
for i in range(ord('a'), ord('z')+1):
idx = i - ord('a')
mod_idx = ( idx + 2 ) % 26
c = chr( mod_idx + ord('a') )
print( chr(c) )
そして、これは1行で同じことです(あまりにも醜いIMO)
for i in range(ord('a'), ord('z')+1):
print( chr((( i - ord('a')) + 2 ) % 26 + ord('a')) )
modを扱う場合、1以外の数値からループすると混乱する可能性があります。これが、開始点として1を使用するようにリファクタリングされたコードです。
for i in range(ord('a'), ord('z')+1):
print chr( (i-97+2) % 26) + 97 ) #Subtract 97, do our modulo and shift, then add 97
他の人はあなたのコードの何が悪いのか答えました。モジュロをまったく処理する必要のないソリューションを提示したいと思います。ord
とを使用して前後に変換する際の本質的な詳細に対処する必要がないため、これはよりクリーンな方法だと思いますchr
。
また、文字コードがすべて順番に並んでいない外国語のアルファベットを扱っている場合でも機能します。
>>> from string import ascii_lowercase
>>> from collections import deque
>>> chrs = deque(ascii_lowercase)
>>> chrs.rotate(-2)
>>> print "".join(chrs)
cdefghijklmnopqrstuvwxyzab
これをある種の翻訳またはエンコーディングに使用する場合は、dictを作成するだけで、次のようになります。
>>> tr = dict(zip(ascii_lowercase, chrs))
>>> "".join(tr.get(x, x) for x in "abcd xyz")
'cdef zab'