Алгоритм, используемый для эффективного поиска LCS между двумя строками:
Определите две строки, 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--;
}
Однако использование вложенных циклов for может занять O(m n) как во времени, так и в пространстве.
Как оптимизировать временную сложность и пространство сложность этого алгоритма?
Алгоритм, используемый для эффективного поиска LCS между двумя строками: [list] [*]Определите две строки, string1 и string2, длиной m и n соответственно.< /li> Создайте двумерный массив dp размерами (m+1) x (n+1). Инициализируйте все элементы dp значением 0. [*]Перебираем символы строки1 слева направо (i) и строки2 сверху вниз (j). [*]Если строка1[i] равна строке2[j], увеличьте dp[i+1][j+1] на 1. Это означает, что текущие символы совпадают, а длина LCS, заканчивающейся в этой точке, равна на один больше, чем LCS, заканчивающийся предыдущими символами. [*]Если строка1[i] не равна строке2[j], возьмите максимальное значение между dp[i][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[i][j-1] больше, чем dp[i-1][j], или переместите вверх, если dp[i-1][j] больше.[*]Повторяйте шаг 7, пока не дойдете до верхнего левого угла массива dp. [/list] Следуя этому алгоритму, самая длинная общая подпоследовательность между в программировании можно встретить две строки. Пример кода Java: [code]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--; } [/code] Однако использование вложенных циклов for может занять O(m n) как во времени, так и в пространстве. Как оптимизировать временную сложность и пространство сложность этого алгоритма?
У меня есть две строки: s1 и s2, и мне нужно найти длину самой длинной подстроки, которая встречается в обеих строках. Подстрока должна быть непрерывной как в s1, так и в s2.
Например:
Если s1 = abcde и s2 = cdefg , самой длинной общей подстрокой...
Я работаю над проблемой, где мне нужно найти самую длинную подпоследовательность заданного массива, которая может образовать палиндром, удалив ровно один элемент. Решение необходимо реализовать рекурсивно.
Например:
Ввод:
Вывод: 1
Пояснение: каждое...
Я работаю над проблемой, где мне нужно найти самую длинную подпоследовательность заданного массива, которая может образовать палиндром, удалив ровно один элемент. Решение необходимо реализовать рекурсивно.
Например:
Ввод:
Вывод: 1
Пояснение: каждое...
Этот небольшой скрипт находит файлы и папки, рекурсивно анализируя структуры каталогов и возвращая пути, которые они хранятся. Это было сделано с единственной целью найти папку на моем D Drive. В то время как код функционирует эффективно, время...
Этот небольшой скрипт находит файлы и папки, рекурсивно анализируя структуры каталогов и возвращая пути, которые они хранятся. Это было сделано с единственной целью найти папку на моем D Drive. В то время как код функционирует эффективно, время...