すでに簡潔な回答が寄せられているのですが、この問題は「最長共通文字列」を探す問題と似ているので、以下のような方法が効率がよいと思いました。
まず問題としては、文字列1の i 番目の文字と文字列2の j 番目の文字からそれぞれ始めて、共通する最長の文字列が何文字になるかを確認して、そのような共通文字列の中で最も長いものを返すような i, j の組み合わせを、すべての可能なi, j の組み合わせの中から探す、ということだと思います。
i, j についていえば、文字列1と2を含む Perl 変数をそれぞれ $s1, $s2 とすると、その範囲はそれぞれ 1<= i <= length($s1)、1<= j <= length($s2) になります。
ところで、ある i, j の組み合わせについては最長文字列の長さが仮に k と分かっているとき、組み合わせi-1, j-1から始まる最長文字列の長さは、文字列1の(i-1)番目と文字列2の(j-1)番目の文字が同じであれば k+1、そうでなければ 0 とすぐにわかるので、実は、このようにすでにわかっている情報を用いることで length($s1) * length($s2) 回の確認でこの作業をすませることができることになります。
ということで、以下のような手続きを書いてみました。
($text1, $text2) = ("oomori-yakiniku","niku-yakisoba");
print &text_match($text1,$text2);
sub text_match {
@s1=split(//,$_[0]);
@s2=split(//,$_[1]);
$match=””;
foreach $i (reverse (0..$#s1)) {
foreach $j (reverse (0..$#s2)) {
if($s1[$i] eq $s2[$j]) {
$c{join(",",($i,$j))}=$c{join(",",($i+1,$j+1))}+1;
$match=join("",@s1[$i..($i+$c{join(",",($i,$j))}-1)])
if($c{join(",",($i,$j))}>length($match));
}
}
}
return $match;
}
お礼
なるほど!がっちり動きますね。 初心者なので一部意味がわかりませんでしたが、使えそうです。しかしやっぱり用意された関数はないのですね? ありがとうございました。