- 想定した解法
def submatch(s,i,p,w)
j=0
while j< w && s[(i+j)..(i+j)]==p[j..j]
j=j+1
end
j
end
def match_safe(s,p)
i=0
w=p.length()
while i+w<=s.length() && submatch(s,i,p,w)< w
i=i+1
end
if(i+w>s.length())
-1
else
i
end
end
- 終了条件を変えて,
def match_safe(s,p)
i=0
w=p.length()
while i<=s.length() && submatch(s,i,p,w)< w
i=i+1
end
if(i>s.length())
-1
else
i
end
end
のようにしても動いてしまう.たとえば,
match_safe("abra","ca")
を実行した時に,i=4の時に,submatch("abra",4,"ca",2)のような呼び出しをおこい,
s[4..4]
のような文字列の範囲(有効なインデックスは0から3まで)を超えた部分文字列の
指定をおこなうことになるが,Ruby言語ではこのようなケースでもエラーにならず,
irb(main):080:0> "abra"[4..4]
=> ""
irb(main):081:0> "abra"[5..5]
=> nil
のように,空文字列やnilを返し
s[(i+j)..(i+j)]==p[j..j]
が成立せずにsubmatchが終了するためである.ただ,結果的に無駄な計算をしていることになるし,他のプログラミング言語では
エラーになることが多いので,注意深くプログラムした方が良い.
- 講義で扱っていないreturnを使うと
def match_safe(s,p)
i=0
w=p.length()
while submatch(s,i,p,w)< w
i=i+1
if i+w>s.length()
return -1
end
end
i
end
あるいは,
def match_safe(s,p)
w=p.length()
for i in 0..(s.length()-w)
if submatch(s,i,p,w)==w
return i
end
end
-1
end
のように書ける.