Ruby 如何正确使用地图和地图!方法
我正在研究凯撒密码,这是一种真正简单的密码,它根据给定的密钥将消息中的每个字母向右移动。例如,如果密钥为3,则消息“hello”将被加密为“ifmmp” 我已经写了这个程序作为一系列的循环是。。。我忘了这个词,但它是一个循环中的一个循环。我一时想不起这个词 无论如何,我这样做的方式是首先将消息(可能由多个语句组成)转换为一个单词数组 然后,我将这些单词转换成一个字母数组,这样我就可以分别移动它们 最后,我将字母数组合并为单个单词,并将单词数组合并回单个消息 我遇到的问题是,每当我试图使用地图和地图!方法,我无法使移位的字母保持其值。我来自C/C++背景,在这些语言中,我这样做不会有问题,因为我了解指针和引用是如何工作的,但我不知道在Ruby中是如何工作的 我的问题是:如何使数组的值在循环内更改,并且在退出循环后不重置回其原始值?注释代码如下:Ruby 如何正确使用地图和地图!方法,ruby,Ruby,我正在研究凯撒密码,这是一种真正简单的密码,它根据给定的密钥将消息中的每个字母向右移动。例如,如果密钥为3,则消息“hello”将被加密为“ifmmp” 我已经写了这个程序作为一系列的循环是。。。我忘了这个词,但它是一个循环中的一个循环。我一时想不起这个词 无论如何,我这样做的方式是首先将消息(可能由多个语句组成)转换为一个单词数组 然后,我将这些单词转换成一个字母数组,这样我就可以分别移动它们 最后,我将字母数组合并为单个单词,并将单词数组合并回单个消息 我遇到的问题是,每当我试图使用地图和地
def caesar_cipher(message,key)
#Convert message to array
message = message.split(' ')
#Map each word in the array to the cipher method
message.map! do |word|
puts "message is: #{message} and the current word is: #{word}"
#Split each word into an array of characters
word = word.split('')
puts "after splitting word is: #{word.inspect}"
#Map each letter to cipher function
word.map do |letter|
puts "trying to shift the letter: #{letter.inspect}"
#Based on the value of the key, each letter will be shifted to the right key times
key.times do
#Cases when the letter is at the end of the alphabet
case letter
when "z"
letter = "a"
when "Z"
letter = "A"
#By default, each letter will be shifted to the next letter in the alphabet per each iteration of the loop
else
letter = letter.next!
end
puts "the letter is now: #{letter.inspect}"
end
#Join the array of letters back into a single word
word = word.join('')
puts "after joining word is: #{word.inspect}"
end
end
#Join the array of words back into the shifted message
message.join(' ')
end
你的代码基本上很好。我只做了两个小补丁
def caesar_cipher(message,key)
message = message.split(' ')
message.map! do |word|
word = word.split('')
word.map! do |letter| # or word = word.map
key.times do
case letter
when "z"
letter = "a"
when "Z"
letter = "A"
else
letter = letter.next!
end
end
letter # return the next letter from the block
end
word.join('')
end
message.join(' ')
end
puts caesar_cipher('hello', 2)
# >> jgnnq
你做错了什么
- 这些值没有保留更改,因为您没有保存它们(
不会更改原始数组,它会返回更改后的副本)map
- 有时,
的返回值是word.map
letter.next代码>(因为它是块中计算的最后一个表达式),它是一个数字,而不是一个字母。你需要总是把信还给我
- 这不是对这个问题的直接回答,但您可能会发现一种更实用的方法很有用
我试图尽可能减少嵌套循环和条件分支逻辑,因为遵循它们可能会非常痛苦
def caesar_cipher(message, key)
key.times do
message = message
.split("")
.map(&:ord) # convert each character to ascii number
.map(&:next) # increment ascii number by 1
.map(&:chr) # convert ascii number back to character
.join
.gsub("{", "a") # fix characters out of range
.gsub("[", "A")
end
message
end
我已经更新了缩进以反映实际代码。。。查看循环中不应该出现的问题-当试图找出问题所在时,通常最好使用
put
打印循环每次迭代中的当前消息/单词/字母,以查看每个循环得到的结果。。。它通常会非常清楚地说明问题所在。我会在你的代码中添加一些puts语句,你应该试着用它们运行它,看看输出是什么ruby注释不是这样工作的:)是的,对不起,我在发布代码之前添加了这些注释,我忘了ruby注释带有#。编辑以修复更常见的嵌套循环。太棒了!就是这样。。。谢谢你认为你能解释我做错了什么吗?我知道你在修改中发表了评论,但我不确定我所做的到底出了什么问题。用替换.map{digit | digit+=1}
.map(&:next)
@SergioTulentsev:啊,不错。