2017-03-15 9 views
1
def caesar_cipher(string, shift_factor) 
    string.length.times do |i| 
    if string[i].ord >= 97 && (string[i].ord + shift_factor) <= 122 || string[i].ord >= 65 && (string[i].ord + shift_factor) <= 90 
     string[i] = (string[i].ord + shift_factor).chr 
    elsif string[i].ord >= 97 && string[i].ord <= 122 || string[i].ord >= 65 && string[i].ord <= 90 
     string[i] = (string[i].ord + shift_factor - 122 + 96).chr 
    end 
    end 
    string 
end 
puts "Enter a string:" 
string_input = gets.chomp 
puts "Enter shift factor:" 
shift_factor_input = gets.chomp.to_i 
result_string = caesar_cipher(string_input, shift_factor_input) 
puts result_string 

https://github.com/OlehSliusar/caesar_cipher誰かがこのRubyコードの2行目から9行目まで説明できますか?

列とシフト係数を取り込み、その後、変更された文字列を出力するコマンドラインシーザー暗号。

私はコード行2を9行目で理解できません。私は混乱しています。この文脈ではの方法が使用される。誰かが私に2行目から9行目まで何をしているのか説明してもらえますか?私がどのように理解したかメソッドは、指定された時間数に基づいて繰り返しとして反復子として機能するということです。

だから5.times { puts "Dog" } =>とすると、「Dog」が5回置かれます。したがって、方法に関する私の理解は、著者がそれを使用した方法とは非常に異なっています。

+1

SOユーザーは怠け者であるため、コードを見るためのリンクには行きません。ここに貼り付けてください。 – corn3lius

+0

'.times'がここで意図した通りに使用されます。 msgstr "この文字列に文字がある回数だけこのループを実行し、現在の反復インデックスをブロックに渡します" msgid。そしてブロックは、渡されたインデックスで何かをすることができます。この場合、それはシーザー暗号のことです(何らかのロジックに基づいて現在のchar、 'string [i]'を変更します) –

+0

@SergioTulentsevこんにちは文字列[i]はどういう意味ですか? 3行目 – roppo

答えて

0

おそらくこれは、それを説明します:

string = 'foo' 
string.length.times {|i| puts string[i]} 

その文字列の各文字を反復処理する方法を。彼らは、経由して同じことを行うことができ、おそらく:

string.chars.collect{|character| p(character)}.join 

と例えば

このコード(p(character)は、現在の文字の必要な操作によって置き換えられる)、結果としてクリーンなコードを持っている:

'foo'.chars.collect{|c| (c.ord + 1).chr}.join 

文字列を繰り返し、各文字がアルファベットの次の文字に置き換えられた新しい文字列を返します。つまり:"gpp"

+0

'.times'。文字列を_mutate_するためにインデックスが使用されます。代わりに 'map' +' join'を使うことができます。 –

+0

'.collect {| c | puts c} ' - 私はそうは思わない:) –

+0

私は同様に考える - 私は' collect'と 'join'で自分の答えを更新したばかりだった – ReggieB

0

.times doは、あなたが言ったように「このコードを特定の回数実行する」という意味です。

.times do |i|は、特定の回数ループしi

string.length内の各時間をカウント文字列の文字数を取得します。

string.length.timesは、文字列の文字数に等しい回数のコードブロックを実行します。

string[i]は、文字列のi番目の文字にアクセスします。

はすべて一緒にそれを置く:

string.length.times do |i| 
    do_stuff_with string[i] 
end 

あなたがそれに何かをする文字列の各文字を反復処理し、コードを持っています。この場合、コードはシーザー暗号に従って各文字をシフトします。

他の言語のstring.each_charまたはforeach(item in items)のようなイテレータを使用すると、反復処理中はコレクションを変更できません。 .timesstring[i]を使用すると、コードが反復処理中に文字列を変更できるようになります。ループは文字列を追跡しないので、何回か実行する必要があることが分かります。

他の人も指摘しているように、このコードの機能はより洗練されたルビー風の方法ですが、コードの作者は普通のプログラミングであるforループのように機能するので.timesを選択しましたパラダイム。

+0

実際にstring [i]は文字列のi番目の文字にアクセスしますか?これは私には本当に直感的ではありません、推論があるのか​​、まさにそのようなものです。 – roppo

1

これは、質問に答えることができない拡張コメントです(アップアップしないでください)。

このコードは、醜くて、不可解であり、Rubyのようなものではありません。 Rubyのツールを使いやすくし、効果的に自己文書化する別の方法があります。

コード

def caesar_cipher_encrypt(string, shift_size) 
    mapping = Hash.new { |h,k| k }. 
       merge(make_map('a', shift_size)). 
       merge(make_map('A', shift_size)) 
    string.gsub(/./, mapping) 
end 

def make_map(first_char, shift_size) 
    base = first_char.ord 
    26.times.with_object({}) { |i,h| h[(base+i).chr] = (base+((i+shift_size) % 26)).chr } 
end 

shift_size = 2 
encrypted_str = caesar_cipher_encrypt("Mary said to Bob, 'Get lost!'.", shift_size) 
    #=> "Octa uckf vq Dqd, 'Igv nquv!'." 

説明

は、最初のステップは、自分のシフト対応に文字をマップするハッシュを作成することです。

h = Hash.new { |h,k| k } 
    #= {} 

これは、ブロックによって指定されたデフォルト値で空のハッシュを作成します。つまり、hにキーkがない場合、h[k]kを返します。 'h'のすべてのキーは文字であるため、数字、スペース、句読点などの文字以外の値はそれ自体になります。 Hash::newを参照してください。

私たちは、その後、我々は今、単純な置換を実行するためにハッシュを使用していますString#gsubの形式を使用することができ

f = make_map('a',2) 
    #=> {"a"=>"c", "b"=>"d", "c"=>"e",..., "x"=>"z", "y"=>"a", "z"=>"b"} 
g = h.merge(f) 
    #=> {"a"=>"c", "b"=>"d", "c"=>"e",..., "y"=>"a", "z"=>"b"} 
f = make_map('A',2) 
    #=> {"A"=>"C", "B"=>"D", "C"=>"E",..., "X"=>"Z", "Y"=>"A", "Z"=>"B"} 
mapping = g.merge(f) 
    #=> {"a"=>"c", "b"=>"d", "c"=>"e",..., "y"=>"a", "z"=>"b", 
    # "A"=>"C", "B"=>"D", "C"=>"E",..., "Y"=>"A", "Z"=>"B"} 
mapping['!'] 
    #=> "!" 

を持っています。次のようにそれを解読することができる

暗号化されたメッセージの受信を復号化

"Mary said to Bob, 'Get lost!'.".gsub(/./, mapping) 
    #=> "Octa uckf vq Dqd, 'Igv nquv!'." 

def caesar_cipher_decrypt(string, shift_size) 
    caesar_cipher_encrypt(string, -shift_size) 
end 

caesar_cipher_decrypt(encrypted_str, shift_size) 
    #=> "Mary said to Bob, 'Get lost!'." 
関連する問題