Techioz Blog

Ruby での文字列比較が正しいテストを返さない

概要

回文をテストしようとしていますが、このコードはテストで true を返しません。

for a in (0..(myString.length/2)) do
  if (myString[a] == myString[myString.length-a+1])
    p = true
  else
    p = false
  end
end

私には何が欠けているのでしょうか?

私はすでにさまざまな等価性と文字列メソッドを試しました。

ありがとう

解決策

コードには 2 つの問題があります。

まず、比較における 2 番目の文字のインデックスが正しく計算されません。最初の反復を例として見てみましょう。最初の反復では、a は 0 になります。つまり、2 番目の文字の位置は (文字列のレースカーを想像してください) 7-0+1 = 8 と計算され、文字列の範囲外になります。代わりに、インデックスは 0 からカウントを開始するため、文字列の最後の文字のインデックスは 6 になります。

これは、myString.length -a-1 のように 2 番目のインデックスを計算することで修正できます。

2 番目の問題は、2 つの文字が一致しない場合にすぐに返されないことです。 abbc という文字列を想像してください。最初の反復では、a と c が比較され、p は false に設定されます。ただし、次の反復では b と b が比較され、p は true に変更されます。ただし、最初の反復では、文字列が回文ではないことがすでに証明されています。

実装を次のように変更することをお勧めします。

def palindrome?(string)
  0.upto(string.length / 2 - 1).all? { |i| string[i] == string[-i - 1] }
end

palindrome?('racecar')
#=> true

palindrome?('foobar')
#=> false

Integer#upto と Array#all のドキュメントを参照してください。 String#[] が負のインデックスでどのように動作するか。