1

我正在尝试解决Ruby中最长的回文问题,我在stackoverflow上找到了答案:

回答:

假设字符串有 n 个字符。首先看看整个字符串是否是回文。如果是,则返回字符串。菲尼!如果不是,请查看长度为 n-1 的两个子串中的任何一个是否是回文。如果有,请退回。如果不是,则检查长度为 n-2 的子串,依此类推。只要字符串包含至少一个字母,就会找到最长的回文。

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    return ana.join if ana
  end
end

puts longest_palindrome "ilikeracecar"

但我无法理解这一行:

return ana.join if ana

做什么

if ana

意思是?

还有为什么这行不通?

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    return ana.join
  end
end

当我运行它时,它给了我

undefined method `join' for nil:NilClass (NoMethodError)

但是我不明白为什么当我检测到第一个满足条件的数组时 ana 会是 ["r", "a", "c", "e", "c", "a" , "r"] 所以这不应该在 ana 中吗?

4

1 回答 1

3

每次运行此代码时:

ana = arr.each_cons(n).detect { |b| b == b.reverse }

ana获得一个新值。detect将返回第一个回文元素或nil. n所以在没有回文的长度的情况下,ana将是nil

return ana.join if ana

表示“如果ana为真(例如非零),则返回ana.join”。在您修改过的代码中,有时anais ,无论如何nil您都尝试使用它。join

如果添加一些日志记录,可能会更容易理解代码:

def longest_palindrome(str)
  arr = str.downcase.chars
  str.length.downto(1) do |n|
    puts "n = #{n}"
    ana = arr.each_cons(n).detect { |b| b == b.reverse }
    if ana == nil then
      puts "ana is nil"
    else
      puts "ana = #{ana.join}"
    end
    return ana.join if ana
  end
end

puts longest_palindrome('a racecar')

输出:

n = 9
ana is nil
n = 8
ana is nil
n = 7
ana = racecar
racecar

如您所见,ana直到nil您缩小到 7 号。

于 2016-07-17T03:18:10.670 回答