Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4aea629

Browse files
committed
Longest common substring & Edit distance added
1 parent 4dac109 commit 4aea629

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

‎AlgorithmCode/EditDistance.java‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* An implementation of the edit distance algorithm
3+
*
4+
* <p>Time Complexity: O(nm)
5+
*
6+
* @author Micah Stairs
7+
*/
8+
9+
public class EditDistance {
10+
11+
// Computes the cost to convert a string 'a' into a string 'b' using dynamic
12+
// programming given the insertionCost, deletionCost and substitutionCost, O(nm)
13+
public static int editDistance(
14+
String a, String b, int insertionCost, int deletionCost, int substitutionCost) {
15+
16+
final int AL = a.length(), BL = b.length();
17+
int[][] arr = new int[AL + 1][BL + 1];
18+
19+
for (int i = 0; i <= AL; i++) {
20+
for (int j = (i == 0 ? 1 : 0); j <= BL; j++) {
21+
22+
int min = Integer.MAX_VALUE;
23+
24+
// Substitution
25+
if (i > 0 && j > 0)
26+
min = arr[i - 1][j - 1] + (a.charAt(i - 1) == b.charAt(j - 1) ? 0 : substitutionCost);
27+
28+
// Deletion
29+
if (i > 0) min = Math.min(min, arr[i - 1][j] + deletionCost);
30+
31+
// Insertion
32+
if (j > 0) min = Math.min(min, arr[i][j - 1] + insertionCost);
33+
34+
arr[i][j] = min;
35+
}
36+
}
37+
38+
return arr[AL][BL];
39+
}
40+
41+
public static void main(String[] args) {
42+
43+
String a = "abcdefg";
44+
String b = "abcdefg";
45+
46+
// The strings are the same so the cost is zero
47+
System.out.println(editDistance(a, b, 10, 10, 10));
48+
49+
a = "aaa";
50+
b = "aaabbb";
51+
52+
// 10*3 = 30 because of three insertions
53+
System.out.println(editDistance(a, b, 10, 2, 3));
54+
55+
a = "1023";
56+
b = "10101010";
57+
58+
// Outputs 2*2 + 4*5 = 24 for 2 substitutions and 4 insertions
59+
System.out.println(editDistance(a, b, 5, 7, 2));
60+
61+
a = "923456789";
62+
b = "12345";
63+
64+
// Outputs 4*4 + 1 = 16 because we need to delete 4
65+
// characters and perform one substitution
66+
System.out.println(editDistance(a, b, 2, 4, 1));
67+
}
68+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* This file contains an implementation of finding the Longest Common Substring (LCS) between two
3+
* strings using dynamic programming.
4+
*
5+
* <p>Time Complexity: O(nm)
6+
*
7+
* @author William Fiset, william.alexandre.fiset@gmail.com
8+
*/
9+
10+
public class LongestCommonSubstring {
11+
12+
// Returns a non unique Longest Common Substring
13+
// between the strings str1 and str2 in O(nm)
14+
public static String lcs(char[] A, char[] B) {
15+
16+
if (A == null || B == null) return null;
17+
18+
final int n = A.length;
19+
final int m = B.length;
20+
21+
if (n == 0 || m == 0) return null;
22+
23+
int[][] dp = new int[n + 1][m + 1];
24+
25+
// Suppose A = a1a2..an-1an and B = b1b2..bn-1bn
26+
for (int i = 1; i <= n; i++) {
27+
for (int j = 1; j <= m; j++) {
28+
29+
// If ends match the LCS(a1a2..an-1an, b1b2..bn-1bn) = LCS(a1a2..an-1, b1b2..bn-1) + 1
30+
if (A[i - 1] == B[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
31+
32+
// If the ends do not match the LCS of a1a2..an-1an and b1b2..bn-1bn is
33+
// max( LCS(a1a2..an-1, b1b2..bn-1bn), LCS(a1a2..an-1an, b1b2..bn-1) )
34+
else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
35+
}
36+
}
37+
38+
int lcsLen = dp[n][m];
39+
char[] lcs = new char[lcsLen];
40+
int index = 0;
41+
42+
// Backtrack to find a LCS. We search for the cells
43+
// where we included an element which are those with
44+
// dp[i][j] != dp[i-1][j] and dp[i][j] != dp[i][j-1])
45+
int i = n, j = m;
46+
while (i >= 1 && j >= 1) {
47+
48+
int v = dp[i][j];
49+
50+
// The order of these may output different LCSs
51+
while (i > 1 && dp[i - 1][j] == v) i--;
52+
while (j > 1 && dp[i][j - 1] == v) j--;
53+
54+
// Make sure there is a match before adding
55+
if (v > 0) lcs[lcsLen - index++ - 1] = A[i - 1]; // or B[j-1];
56+
57+
i--;
58+
j--;
59+
}
60+
61+
return new String(lcs, 0, lcsLen);
62+
}
63+
64+
public static void main(String[] args) {
65+
66+
char[] A = {'A', 'X', 'B', 'C', 'Y'};
67+
char[] B = {'Z', 'A', 'Y', 'W', 'B', 'C'};
68+
System.out.println(lcs(A, B)); // ABC
69+
70+
A = new char[] {'3', '9', '8', '3', '9', '7', '9', '7', '0'};
71+
B = new char[] {'3', '3', '9', '9', '9', '1', '7', '2', '0', '6'};
72+
System.out.println(lcs(A, B)); // 339970
73+
}
74+
}

‎ProblemSolvingCodeBOJ/CodingQuestion17_11.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public static void check(Point dot1, Point dot2) {
4444
public static void main(String[] args) {
4545
dot1();
4646
System.out.println(max);
47+
//Output:
48+
// 9
4749
}
4850

4951
static class Point {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /