我试图将我的哈希值作为连接字符串写入变量。
original_string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
cipher_key = "honeyL"
message_string = "hEllo world"
deleted_string = original_string.delete!(cipher_key)
altered_string = cipher_key + deleted_string
encryption_hash = Hash.new
i = 0
while(i < original_string.length)
encryption_hash [original_string[i]] = altered_string[i].to_s
i += 1
end
encrypted_message = ""
count = 0
while(count < message_string.length)
if(message_string[count] == " ")
encrypted_message << message_string[count]
else
encrypted_message << encryption_hash[message_string[count]]
end
count += 1
end
puts encrypted_message
我在第24行有问题,但我不知道为什么。如果我使用encryption_hash[original_string[count]]
而不是encryption_hash[message_string[count]]
,那么它将起作用。但是我不知道为什么。请解释。
答案 0 :(得分:2)
因此这应该有助于您走上正确的道路。我不确定您项目的预期结果是100%不确定的,但是这里有一个简短的原创与重写以及对发生的事情的解释。
original_string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
cipher_key = "honeyL"
message_string = "hEllo world"
# Using the delete! method is actually altering the original_string in memory. You want to use the plane delete method.
deleted_string = original_string.delete!(cipher_key)
altered_string = cipher_key + deleted_string
# This is a fair amount of code for a simple mapping
encryption_hash = Hash.new
i = 0
while(i < original_string.length)
encryption_hash [original_string[i]] = altered_string[i].to_s
i += 1
end
encrypted_message = ""
count = 0
# Because you deleted the message characters from the original_string BEFORE creating you encryption_hash, you're getting null value on the look up.
while(count < message_string.length)
if(message_string[count] == " ")
encrypted_message << message_string[count]
else
encrypted_message << encryption_hash[message_string[count]]
end
count += 1
end
puts encrypted_message
base_str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
message = 'hEllo world'
key = 'honeyL'
# Using delete instead of delete!
altered_str = key + base_str.delete(key)
# Zip together characters and create hash from grouped array
encryption_hash = Hash[base_str.chars.zip(altered_str.chars)]
encryption_hash[' '] = ' '
encrypted_message = ''
# Loop through non-inclusive range concatenating encrypted values to string
for i in 0...message.length
encrypted_message << encryption_hash[message[i]]
end
puts encrypted_message
我浏览了一些建议的迭代器,以查看哪个迭代器的性能最佳,并且所有迭代器都相对相同(使用8,145,000个字符消息):
encrypted_message = message.gsub(/./) { |chr| encryption_hash[chr] }
# {"ruby":"2.3.0","elapsed_time":3.24,"garbage_collection":"on","memory_used":"8 MB","garbage_collection_count":456}
message.each_char { |m| encrypted_message << encryption_hash[m] }
# {"ruby":"2.3.0","elapsed_time":2.06,"garbage_collection":"on","memory_used":"8 MB","garbage_collection_count":456}
(0...message.length).each { |i| encrypted_message << encryption_hash[message[i]] }
# {"ruby":"2.3.0","elapsed_time":2.21,"garbage_collection":"on","memory_used":"8 MB","garbage_collection_count":456}
for i in 0...message.length
encrypted_message << encryption_hash[message[i]]
end
# {"ruby":"2.3.0","elapsed_time":2.21,"garbage_collection":"on","memory_used":"8 MB","garbage_collection_count":456}
也就是说,我发现gsub
可以将哈希作为其第二个参数,用于匹配字符上的替换映射。这是在同一个球场上进行的。
message.gsub!(/[a-zA-Z]/, encryption_hash)
# {"ruby":"2.3.0","elapsed_time":2.45,"garbage_collection":"on","memory_used":"8 MB","garbage_collection_count":388}
最终,我认为这是最好的解决方案。原因是它不需要对原始字符串进行预格式化,也不会丢失任何未映射的值。例如,在原始答案中,所有标点符号或数字都将被省略和丢失。使用这种gsub
方法,您只能加密要加密的字符集,其余部分保持不变。
这简化了解决方案:
base_str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
message = 'hEllo world'
key = 'honeyL'
altered_str = key + base_str.delete(key)
encryption_hash = Hash[base_str.chars.zip(altered_str.chars)]
message.gsub!(/[a-zA-Z]/, encryption_hash)
puts message
答案 1 :(得分:1)
您在此行遇到错误:
encrypted_message << encryption_hash[message_string[count]]
因为message_string[count]
从您的h
返回hEllo world
,但是您的encryption_hash
是没有h
键的哈希值,也没有{{1 }}个字符。
呼叫honeyL
时,original_string.delete!(cipher_key)
突变了delete!
,从original_string
中删除了6个字符
将原始字符串替换为消息字符串的原因起作用:
cipher_key
在您的示例中,pry >> original_string
=> "abcdfgijklmpqrstuvwxzABCDEFGHIJKMNOPQRSTUVWXYZ"
pry >> message_string
=> "hEllo world"
为0(您在第一次迭代中),因此它正在寻找0的索引。 count
的0索引是original_string
,它存在于您的a
中。 encryption_hash
的0索引是message_string
,在您的h
中不存在。
我不确定解决方案是什么,因为我不确定预期的结果。但这就是原因所在。要对其进行调试,可以尝试encryption_hash
,然后在ruby文件的顶部添加:
gem install pry pry-byebug
然后,在require 'pry'
require 'pry-byebug
语句后的新行中,添加else
。运行您的脚本,它将在该行“停止”。您可以使用binding.pry
检查此时的所有变量。
使用puts
退出撬动,然后使用exit
重置代码中停止位置的视图。您还可以使用whereami
来评估一行。