Ruby 最长回文

Ruby longest palindrome

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

答案:

假设字符串有n个字符。先看整个字符串是不是回文。如果是,return 字符串。完了!如果不是,则查看长度为 n-1 的两个子串中是否有一个是回文。如果是,return 它。如果不是,则检查长度为 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 会是 nil ["r", "a", "c", "e"、"c"、"a"、"r"] 所以这不应该在 ana 中吗?

这段代码每次运行时:

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

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

return ana.join if ana

表示"if ana is true (e.g. non-nil), return ana.join"。在您修改的代码中,有时 ananil,而您仍然尝试 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

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