標準9251:LCS[LCS,DP]
16028 ワード
9251号:LCS 文字列のLongestCommon Subescence(最長共通部分数列)を探す問題です. 2つの文字列が与えられると、すべての部分数列の中で最も長い1つが検索される. ACAYKPとCAPCAKのLCSはACAKです. コードのarrayは、2つの文字列の共通部分の個数を格納する配列である.array[i][j]を表す
str 2の0~(i−1)サブストリングとstr 1の0~(j−1)サブストリングのLCS長さ.
arrayの行値を2番目の入力(文字列の長さ+1)に設定します. arrayのcol値を最初の入力(文字列長+1)に設定します. +1を行ったのは、次のサイクルの点火式でIndexOutOfBoundExceptionが出ないようにするためです. 点火式の説明の現在のインデックスの文字が同じであれば、LCS長に1文字が追加されたことを示し、上述した点化方式を形成する. 点火式の説明現在のインデックスの文字が異なります.この場合、従来のLCSが維持されるため、上記点火式が形成される. 時間の複雑さ O(N2)O(N^2)O(N2) → N = string length LongestCommon Subsequence出力法点火式によれば、配列の最後の行、最後のcolは配列の最大値を格納する. このインデックスから、配列の上、左の値をチェックし、自分と同じ数字があればrow、colの値を更新します. 自身と同じ値が存在しない場合は、row、col値を左上隅で更新します. および更新前に、インデックスに対応する文字が任意の空間に格納される. ビット目のプロシージャを配列値0に繰り返します. 最後に保存した文字列の逆順文字列を出力するとLCSが出力されます.
package string
import java.io.*
fun main():Unit = with(BufferedReader(InputStreamReader(System.`in`))){
val str1 = readLine().trim()
val str2 = readLine().trim()
val array = Array<Array<Int>>(str2.length+1){Array<Int>(str1.length+1){0}}
for (i in 1 until str2.length+1){
for (j in 1 until str1.length+1){
if (str1[j-1] == str2[i-1]){
array[i][j] = array[i-1][j-1]+1
}else{
array[i][j] = array[i-1][j].coerceAtLeast(array[i][j-1])
}
}
}
println(array.last().last())
}
説明:str 2の0~(i−1)サブストリングとstr 1の0~(j−1)サブストリングのLCS長さ.
if (str1[j-1] == str2[i-1]){
array[i][j] = array[i-1][j-1]+1
}
else{
array[i][j] = array[i-1][j].coerceAtLeast(array[i][j-1])
}
if (array[row-1][col] == array[row][col]){ row = row-1 }
else if (array[row][col-1] == array[row][col]){col = col -1}
else{
lcs.append(str1[col-1])
row = row - 1
col = col - 1
}
var row = array.size-1
var col = array[0].size-1
var lcs = StringBuilder()
while (array[row][col]!=0){
//[row-1][col] or [row][col-1]에 [row][col]값과 같은 값이 있는지 찾기
//있다면 row, col 값 update
//없다면 row = row - 1 and col = col - 1 로 update -> 문자열 값 넣어주기
if (array[row-1][col] == array[row][col]){ row = row-1 }
else if (array[row][col-1] == array[row][col]){col = col -1}
else{
lcs.append(str1[col-1])
row = row - 1
col = col - 1
}
}
println(lcs.toString().reversed())
Reference
この問題について(標準9251:LCS[LCS,DP]), 我々は、より多くの情報をここで見つけました https://velog.io/@jodaehyeon/백준-9251-LCS-LCS-DPテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol