- Определите две строки, string1 и string2, длиной m и n соответственно.< /li>
Создайте двумерный массив dp размерами (m+1) x (n+1). Инициализируйте все элементы dp значением 0. - Перебираем символы строки1 слева направо (i) и строки2 сверху вниз (j).
- Если строка1 равна строке2[j], увеличьте dp[i+1][j+1] на 1. Это означает, что текущие символы совпадают, а длина LCS, заканчивающейся в этой точке, равна на один больше, чем LCS, заканчивающийся предыдущими символами.
- Если строка1 не равна строке2[j], возьмите максимальное значение между dp[j+1] и dp[i+1][j] и сохраните их в dp[i+1][j+1]. Это означает, что текущие символы не совпадают, поэтому длина LCS, заканчивающейся в этой точке, равна максимальной длине LCS, заканчивающейся предыдущими символами в строке 1 или строке 2.
- После итерации все символы, значение dp[m][n] будет длиной LCS между строкой1 и строкой2.
- Чтобы получить фактическую LCS, начните с dp[m][n ] и вернуться через массив dp. Если строка1[i-1] равна строке2[j-1], добавьте символ в LCS и переместите по диагонали к dp[i-1][j-1]. В противном случае переместите влево, если dp[j-1] больше, чем dp[i-1][j], или переместите вверх, если dp[i-1][j] больше.
- Повторяйте шаг 7, пока не дойдете до верхнего левого угла массива dp.
Следуя этому алгоритму, самая длинная общая подпоследовательность между в программировании можно встретить две строки.
Пример кода Java:
Код: Выделить всё
public static String repeatCharacter(char ch, int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(ch);
}
return sb.toString();
}
Scanner myObj = new Scanner(System.in);
char ch = 'X';
System.out.println("Enter size of first string");
int m = myObj.next();
String string1 = repeatCharacter(ch, m);
System.out.println("Enter size of first string");
int m = myObj.next()
String string2 = repeatCharacter(ch, n);
String lcs = "";
System.out.println("Enter first string");
string1 = myObj.nextLine();
System.out.println("Enter second string");
string1 = myObj.nextLine();
int dp[m+1][n+1];
int i, j;
for (i = 0; i < m + 1; i++) {
for (j = 0; j < n + 1; j++) {
dp[i][j] = 0;
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
if (string1[i] = string2[j])
dp[i+1][j+1]++;
else
dp[i+1][j+1] = Math.max(dp[i][j+1], dp[i+1][j]);
}
}
i = m, j = n;
while (i > -1 && j > -1) {
if (string1[i-1] = string2[j-1]) {
lcs = lcs + string1[i-1];
i--;
j--;
}
else if (dp[i][j-1] > dp[i-1][j])
i--;
else
j--;
}
Как оптимизировать временную сложность и пространство сложность этого алгоритма?
Подробнее здесь: https://stackoverflow.com/questions/778 ... nce-lcs-be