1

Ruby で最も長い回文問題を解決しようとしていますが、stackoverflow で答えを見つけました。

答え:

文字列に n 文字があるとします。最初に、文字列全体が回文であるかどうかを確認します。存在する場合は、文字列を返します。フィニ!そうでない場合は、長さ n-1 の 2 つの部分文字列のいずれかが回文であるかどうかを確認します。ある場合は、それを返します。そうでない場合は、長さ n-2 の部分文字列を調べます。文字列に少なくとも 1 つの文字が含まれている限り、最長の回文が検出されます。

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)

しかし、["r"、"a"、"c"、"e"、"c"、"a" という条件を満たす最初の配列を検出したときに、ana が nil になる理由がわかりません。 、「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

は、「anatrue (非 nil など) の場合、返すana.join」ことを意味します。変更されたコードでは、 が になることanaがありますが、とにかくそれ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

ご覧のとおり、サイズananil7になるまでです。

于 2016-07-17T03:18:10.670 に答える