Skip to content

Commit b9f20e1

Browse files
author
Michael Ho
committed
Init project
1 parent 7e4dd45 commit b9f20e1

File tree

5 files changed

+304
-0
lines changed

5 files changed

+304
-0
lines changed

Algorithms-Java.iml

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7+
</content>
8+
<orderEntry type="inheritedJdk" />
9+
<orderEntry type="sourceFolder" forTests="false" />
10+
<orderEntry type="module-library" exported="">
11+
<library name="JUnit5.3">
12+
<CLASSES>
13+
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.4.0/junit-jupiter-api-5.4.0.jar!/" />
14+
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
15+
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.1.1/opentest4j-1.1.1.jar!/" />
16+
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.4.0/junit-platform-commons-1.4.0.jar!/" />
17+
</CLASSES>
18+
<JAVADOC />
19+
<SOURCES />
20+
</library>
21+
</orderEntry>
22+
<orderEntry type="library" exported="" name="org.junit.jupiter:junit-jupiter-engine:5.4.0" level="project" />
23+
<orderEntry type="library" exported="" name="org.junit.jupiter:junit-jupiter:5.4.0" level="project" />
24+
<orderEntry type="library" exported="" name="org.junit.platform:junit-platform-commons:1.4.0" level="project" />
25+
<orderEntry type="library" exported="" name="org.junit.vintage:junit-vintage-engine:5.4.0" level="project" />
26+
</component>
27+
</module>
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package com.michaelho.DynamicProgramming;
2+
3+
import java.util.Arrays;
4+
import java.util.Comparator;
5+
import java.util.List;
6+
7+
/**
8+
* The DP1 class explores a set of dynamic programming questions and solutions such as
9+
* Fibonacci, longest common subsequence (LCS), longest uncommon subsequence (LUS),
10+
* and longest increasing subsequence (LIS).
11+
*
12+
* @author Michael Ho
13+
* @since 2014-09-14
14+
* */
15+
class DP1 {
16+
Fibonacci fib = new Fibonacci();
17+
LIS lis = new LIS();
18+
LUS lus = new LUS();
19+
LCS lcs = new LCS();
20+
21+
/**
22+
* The Fibonacci class explores the methods used to calculate the Fibonacci number.
23+
* Methods include recursive and dynamic programming.
24+
* */
25+
class Fibonacci {
26+
/**
27+
* The recursive method used to calculate Fibonacci numbers. This method
28+
* is inefficient in runtime, which is O(2^N).
29+
*
30+
* @param x The number to be calculated Fibonacci numbers.
31+
* @return int The results of calculation.
32+
* */
33+
int count(int x) {
34+
if (x == 0) {
35+
return 0;
36+
} else if (x == 1) {
37+
return 1;
38+
}
39+
40+
return count(x-1) + count(x-2);
41+
}
42+
/**
43+
* The dynamic programing method used to calculate Fibonacci numbers.
44+
* The method uses storage to reduced duplicate caluculation
45+
*
46+
* @param x The number to be calculated Fibonacci numbers.
47+
* @return int The results of calculation.
48+
* */
49+
int dpCount(int x) {
50+
int[] fArray = new int[x+1];
51+
fArray[0] = 0;
52+
fArray[1] = 1;
53+
54+
for (int i = 2; i <= x; i++) {
55+
fArray[i] = fArray[i-1] + fArray[i-2];
56+
}
57+
58+
return fArray[x];
59+
}
60+
}
61+
/**
62+
* The LCS class use the dynamic programming method to calculate the longest common subsequence
63+
* of given array. Subsequence is different from substring. Subsequence is a subset
64+
* of elements in order that can be derived from another sequence while substring has
65+
* to be a set of consecutive elements.
66+
* */
67+
class LCS {
68+
/**
69+
* The dynamic method used to find the longest length of subsequence. The runtime is O(N^2).
70+
*
71+
* @param s1 The first string to be calculated for longest increasing subsequence.
72+
* @param s2 The second string to be calculated for longest increasing subsequence.
73+
* @return int The results of calculation.
74+
*/
75+
int lengthOfLCS(String s1, String s2) {
76+
return dpFindLongestLength(s1, s2, s1.length() - 1, s2.length() - 1);
77+
}
78+
79+
/**
80+
* The recursive function used to find LCS.
81+
*
82+
* @param s1 The first string to be calculated for longest increasing subsequence.
83+
* @param s2 The second string to be calculated for longest increasing subsequence.
84+
* @param idx1 The index of the first string.
85+
* @param idx2 The index of the second string.
86+
* @return int The results of calculation.
87+
*/
88+
private int dpFindLongestLength(String s1, String s2, int idx1, int idx2) {
89+
if (idx1 < 0 || idx2 < 0) {
90+
return 0;
91+
}
92+
93+
if (s1.charAt(idx1) == s2.charAt(idx2))
94+
return 1 + dpFindLongestLength(s1, s2, idx1 - 1, idx2 - 1);
95+
else
96+
return Math.max(dpFindLongestLength(s1, s2, idx1, idx2 - 1),
97+
dpFindLongestLength(s1, s2, idx1 - 1, idx2));
98+
}
99+
}
100+
/**
101+
* The LUS class explores the method to calculate the longest uncommon subsequence
102+
* of given array of strings.
103+
* */
104+
class LUS {
105+
/**
106+
* The method used to find the longest length of subsequence. The runtime is roughly O(N^2).
107+
*
108+
* @param strs The first string to be calculated for longest increasing subsequence.
109+
* @return int The length of LUS.
110+
* */
111+
int findLUSlength(String[] strs) {
112+
if (strs.length <= 1) return strs.length;
113+
114+
List<String> strsList = Arrays.asList(strs);
115+
strsList.sort(Comparator.comparingInt(String::length).reversed()); // Compare by length
116+
117+
for (int i = 0; i < strsList.size(); i++) {
118+
boolean isLUS = true;
119+
for (int j = 0; j < strsList.size(); j++) {
120+
if (i != j && isSubsequence(strs[i], strs[j])) {
121+
isLUS = false;
122+
break;
123+
}
124+
}
125+
if (isLUS) {
126+
return strs[i].length();
127+
}
128+
}
129+
return -1;
130+
}
131+
132+
boolean isSubsequence(String s1, String s2) {
133+
int i = 0;
134+
int j = 0;
135+
136+
while (i < s1.length() && j < s2.length()) {
137+
if (s1.charAt(i) == s2.charAt(j)) {
138+
i++;
139+
}
140+
j ++;
141+
}
142+
return i == s1.length();
143+
}
144+
}
145+
/**
146+
* The LIS class explores the method to find the length of the longest increasing
147+
* subsequence. Subsequence is different from substring. Subsequence is a subset
148+
* of elements in order that can be derived from another sequence while substring
149+
* has to be a set of consecutive elements.
150+
* */
151+
class LIS {
152+
/**
153+
* The dynamic method used to find the longest length of subsequence. The runtime is O(N^2).
154+
*
155+
* @param array The array to be calculated for longest increasing subsequence.
156+
* @return int The results of calculation.
157+
* */
158+
int dpFindLongestLength(int[] array) {
159+
int max = 1;
160+
int[] countArr = new int[array.length];
161+
162+
// O(N)
163+
for (int i = 0; i < array.length; i++) {
164+
countArr[i] = 1;
165+
// O(N)
166+
for (int j = 0; j < i; j ++) {
167+
if (array[j] < array[i] && countArr[i] < countArr[j] + 1) {
168+
countArr[i] = 1 + countArr[j];
169+
}
170+
}
171+
}
172+
173+
// O(N)
174+
for (int count : countArr) {
175+
max = Math.max(count, max);
176+
}
177+
178+
return max;
179+
}
180+
}
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.michaelho.DynamicProgramming;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertEquals;
6+
7+
public class DPTests {
8+
9+
private DP1 dp1 = new DP1();
10+
11+
@Test
12+
public void testFibonacci() {
13+
int input = 5;
14+
int expected = 5;
15+
fibTest(input, expected);
16+
fibDpTest(input, expected);
17+
}
18+
19+
private void fibTest(int input, int expected) {
20+
int output = dp1.fib.count(input);
21+
assertEquals(expected, output);
22+
}
23+
24+
private void fibDpTest(int input, int expected) {
25+
int output = dp1.fib.dpCount(input);
26+
assertEquals(expected, output);
27+
}
28+
29+
@Test
30+
public void testLIS() {
31+
int[] input = {5, 7, 4, -3, 9, 1, 10, 4, 5, 8, 9, 3};
32+
int expected = 6;
33+
runLIS(input, expected);
34+
}
35+
36+
private void runLIS(int[] input, int expected) {
37+
int output = dp1.lis.dpFindLongestLength(input);
38+
assertEquals(expected, output);
39+
}
40+
41+
@Test
42+
public void testLCS() {
43+
String input1 = "BCDBCDA";
44+
String input2 = "ABECBA";
45+
int expected = 4;
46+
runLCS(input1, input2, expected);
47+
}
48+
49+
private void runLCS(String input1, String input2, int expected) {
50+
int output = dp1.lcs.lengthOfLCS(input1, input2);
51+
assertEquals(expected, output);
52+
}
53+
54+
@Test
55+
public void testLUS1() {
56+
String[] input = {"aba", "cdc", "eae"};
57+
int expected = 3;
58+
runLUS(input, expected);
59+
}
60+
61+
@Test
62+
public void testLUS2() {
63+
String[] input = {"aabbcc", "aabbcc","cb","abc"};
64+
int expected = 2;
65+
runLUS(input, expected);
66+
}
67+
68+
private void runLUS(String[] strs, int expected) {
69+
int output = dp1.lus.findLUSlength(strs);
70+
assertEquals(expected, output);
71+
}
72+
}
73+

src/com/michaelho/Main.java

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.michaelho;
2+
3+
import com.michaelho.DynamicProgramming.DPTests;
4+
import org.junit.runner.JUnitCore;
5+
import org.junit.runner.Result;
6+
import org.junit.runner.notification.Failure;
7+
8+
public class Main {
9+
10+
public static void main(String[] args) {
11+
Result result = JUnitCore.runClasses(DPTests.class);
12+
13+
for (Failure failure : result.getFailures()) {
14+
System.out.println(failure.toString());
15+
}
16+
17+
System.out.println("DPTests successful: " + result.wasSuccessful());
18+
}
19+
20+
public static void print(String s) {
21+
System.out.println(s);
22+
}
23+
}

0 commit comments

Comments
 (0)