VenomFangsの答えを詳しく説明するために、これに対する単純な動的プログラミングソリューションがあります。ここで許可されている操作は文字の挿入(削除、更新なし)のみであると想定していることに注意してください。Sをn文字の文字列とします。このための単純な再帰関数Pは次のとおりです。
= P [i+1 .. j-1], if S[i] = S[j]
P [i..j]
= min (P[i..j-1], P[i+1..j]) + 1,
これが真実である理由についてさらに説明が必要な場合は、コメントを投稿してください。少し考えればわかりやすいですが、喜んで説明します。ちなみに、これは使用するLCS関数の正反対であるため、ソリューションが実際に最適であることを検証します。もちろん、それは完全に可能です、もしそうなら、誰かが私に知らせてくれます!
編集:回文自体を説明するために、これは次のように簡単に行うことができます:
上記のように、P [1..n]は、この文字列を回文にするために必要な挿入数を示します。上記の2次元配列が作成されたら、次のように回文を見つけます。
i = 1、j=nから始めます。ここで、string output = "";
while(i < j)
{
if (P[i][j] == P[i+1][j-1]) //this happens if no insertions were made at this point
{
output = output + S[i];
i++;
j--;
}
else
if (P[i][j] == P[i+1][j]) //
{
output = output + S[i];
i++;
}
else
{
output = S[j] + output;
j--;
}
}
cout<<output<<reverse(output);
//You may have to be careful about odd sized palindromes here,
// I haven't accounted for that, it just needs one simple check
それはより良い読書になりますか?