Merge remote-tracking branch 'upstream/master'
Conflicts: libraries/pom.xml
This commit is contained in:
@@ -41,3 +41,5 @@ SpringDataInjectionDemo/.mvn/wrapper/maven-wrapper.properties
|
|||||||
spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties
|
spring-call-getters-using-reflection/.mvn/wrapper/maven-wrapper.properties
|
||||||
|
|
||||||
spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties
|
spring-check-if-a-property-is-null/.mvn/wrapper/maven-wrapper.properties
|
||||||
|
*.springBeans
|
||||||
|
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ Any IDE can be used to work with the projects, but if you're using Eclipse, cons
|
|||||||
|
|
||||||
CI - Jenkins
|
CI - Jenkins
|
||||||
================================
|
================================
|
||||||
This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/tutorials/)**
|
This tutorials project is being built **[>> HERE](https://rest-security.ci.cloudbees.com/job/github%20projects%20Jobs/job/tutorials/)**
|
||||||
|
|||||||
@@ -8,3 +8,4 @@
|
|||||||
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
- [Check If a Number Is Prime in Java](http://www.baeldung.com/java-prime-numbers)
|
||||||
- [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm)
|
- [Example of Hill Climbing Algorithm](http://www.baeldung.com/java-hill-climbing-algorithm)
|
||||||
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search)
|
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](http://www.baeldung.com/java-monte-carlo-tree-search)
|
||||||
|
- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms)
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
package com.baeldung.algorithms.binarysearch;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionBruteForce {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> it1 = head;
|
||||||
|
int nodesTraversedByOuter = 0;
|
||||||
|
while (it1 != null && it1.next != null) {
|
||||||
|
it1 = it1.next;
|
||||||
|
nodesTraversedByOuter++;
|
||||||
|
|
||||||
|
int x = nodesTraversedByOuter;
|
||||||
|
Node<T> it2 = head;
|
||||||
|
int noOfTimesCurrentNodeVisited = 0;
|
||||||
|
|
||||||
|
while (x > 0) {
|
||||||
|
it2 = it2.next;
|
||||||
|
|
||||||
|
if (it2 == it1) {
|
||||||
|
noOfTimesCurrentNodeVisited++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noOfTimesCurrentNodeVisited == 2) {
|
||||||
|
return new CycleDetectionResult<>(true, it1);
|
||||||
|
}
|
||||||
|
|
||||||
|
x--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionByFastAndSlowIterators {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> slow = head;
|
||||||
|
Node<T> fast = head;
|
||||||
|
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
slow = slow.next;
|
||||||
|
fast = fast.next.next;
|
||||||
|
|
||||||
|
if (slow == fast) {
|
||||||
|
return new CycleDetectionResult<>(true, fast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class CycleDetectionByHashing {
|
||||||
|
|
||||||
|
public static <T> CycleDetectionResult<T> detectCycle(Node<T> head) {
|
||||||
|
if (head == null) {
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Node<T>> set = new HashSet<>();
|
||||||
|
Node<T> node = head;
|
||||||
|
|
||||||
|
while (node != null) {
|
||||||
|
if (set.contains(node)) {
|
||||||
|
return new CycleDetectionResult<>(true, node);
|
||||||
|
}
|
||||||
|
set.add(node);
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CycleDetectionResult<>(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleDetectionResult<T> {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<T> node;
|
||||||
|
|
||||||
|
public CycleDetectionResult(boolean cycleExists, Node<T> node) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalBruteForce {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param loopNodeParam - reference to the node where Flyods cycle
|
||||||
|
* finding algorithm ends, i.e. the fast and the slow iterators
|
||||||
|
* meet.
|
||||||
|
* @param head - reference to the head of the list
|
||||||
|
*/
|
||||||
|
private static <T> void removeCycle(Node<T> loopNodeParam, Node<T> head) {
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
while (it != null) {
|
||||||
|
if (isNodeReachableFromLoopNode(it, loopNodeParam)) {
|
||||||
|
Node<T> loopStart = it;
|
||||||
|
findEndNodeAndBreakCycle(loopStart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
it = it.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> boolean isNodeReachableFromLoopNode(Node<T> it, Node<T> loopNodeParam) {
|
||||||
|
Node<T> loopNode = loopNodeParam;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (it == loopNode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
} while (loopNode.next != loopNodeParam);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void findEndNodeAndBreakCycle(Node<T> loopStartParam) {
|
||||||
|
Node<T> loopStart = loopStartParam;
|
||||||
|
|
||||||
|
while (loopStart.next != loopStartParam) {
|
||||||
|
loopStart = loopStart.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
loopStart.next = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalByCountingLoopNodes {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void removeCycle(Node<T> loopNodeParam, Node<T> head) {
|
||||||
|
int cycleLength = calculateCycleLength(loopNodeParam);
|
||||||
|
Node<T> cycleLengthAdvancedIterator = head;
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
for (int i = 0; i < cycleLength; i++) {
|
||||||
|
cycleLengthAdvancedIterator = cycleLengthAdvancedIterator.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (it.next != cycleLengthAdvancedIterator.next) {
|
||||||
|
it = it.next;
|
||||||
|
cycleLengthAdvancedIterator = cycleLengthAdvancedIterator.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
cycleLengthAdvancedIterator.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> int calculateCycleLength(Node<T> loopNodeParam) {
|
||||||
|
Node<T> loopNode = loopNodeParam;
|
||||||
|
int length = 1;
|
||||||
|
|
||||||
|
while (loopNode.next != loopNodeParam) {
|
||||||
|
length++;
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class CycleRemovalWithoutCountingLoopNodes {
|
||||||
|
|
||||||
|
public static <T> boolean detectAndRemoveCycle(Node<T> head) {
|
||||||
|
CycleDetectionResult<T> result = CycleDetectionByFastAndSlowIterators.detectCycle(head);
|
||||||
|
|
||||||
|
if (result.cycleExists) {
|
||||||
|
removeCycle(result.node, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.cycleExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void removeCycle(Node<T> meetingPointParam, Node<T> head) {
|
||||||
|
Node<T> loopNode = meetingPointParam;
|
||||||
|
Node<T> it = head;
|
||||||
|
|
||||||
|
while (loopNode.next != it.next) {
|
||||||
|
it = it.next;
|
||||||
|
loopNode = loopNode.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
loopNode.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class Node<T> {
|
||||||
|
T data;
|
||||||
|
Node<T> next;
|
||||||
|
|
||||||
|
public static <T> Node<T> createNewNode(T data, Node<T> next) {
|
||||||
|
Node<T> node = new Node<T>();
|
||||||
|
node.data = data;
|
||||||
|
node.next = next;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void traverseList(Node<T> root) {
|
||||||
|
if (root == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> node = root;
|
||||||
|
while (node != null) {
|
||||||
|
System.out.println(node.data);
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Node<T> getTail(Node<T> root) {
|
||||||
|
if (root == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node<T> node = root;
|
||||||
|
while (node.next != null) {
|
||||||
|
node = node.next;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Executable
+194
@@ -0,0 +1,194 @@
|
|||||||
|
package com.baeldung.algorithms.string.search;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class StringSearchAlgorithms {
|
||||||
|
public static long getBiggerPrime(int m) {
|
||||||
|
BigInteger prime = BigInteger.probablePrime(getNumberOfBits(m) + 1, new Random());
|
||||||
|
return prime.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getLowerPrime(long number) {
|
||||||
|
BigInteger prime = BigInteger.probablePrime(getNumberOfBits(number) - 1, new Random());
|
||||||
|
return prime.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getNumberOfBits(final int number) {
|
||||||
|
return Integer.SIZE - Integer.numberOfLeadingZeros(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getNumberOfBits(final long number) {
|
||||||
|
return Long.SIZE - Long.numberOfLeadingZeros(number);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int simpleTextSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
int textSize = text.length;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
int j = 0;
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j += 1;
|
||||||
|
if (j >= patternSize)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int RabinKarpMethod(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length; // m
|
||||||
|
int textSize = text.length; // n
|
||||||
|
|
||||||
|
long prime = getBiggerPrime(patternSize);
|
||||||
|
|
||||||
|
long r = 1;
|
||||||
|
for (int i = 0; i < patternSize - 1; i++) {
|
||||||
|
r *= 2;
|
||||||
|
r = r % prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
long[] t = new long[textSize];
|
||||||
|
t[0] = 0;
|
||||||
|
|
||||||
|
long pfinger = 0;
|
||||||
|
|
||||||
|
for (int j = 0; j < patternSize; j++) {
|
||||||
|
t[0] = (2 * t[0] + text[j]) % prime;
|
||||||
|
pfinger = (2 * pfinger + pattern[j]) % prime;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
boolean passed = false;
|
||||||
|
|
||||||
|
int diff = textSize - patternSize;
|
||||||
|
for (i = 0; i <= diff; i++) {
|
||||||
|
if (t[i] == pfinger) {
|
||||||
|
passed = true;
|
||||||
|
for (int k = 0; k < patternSize; k++) {
|
||||||
|
if (text[i + k] != pattern[k]) {
|
||||||
|
passed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passed) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < diff) {
|
||||||
|
long value = 2 * (t[i] - r * text[i]) + text[i + patternSize];
|
||||||
|
t[i + 1] = ((value % prime) + prime) % prime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int KnuthMorrisPrattSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length; // m
|
||||||
|
int textSize = text.length; // n
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
int[] shift = KnuthMorrisPrattShift(pattern);
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j += 1;
|
||||||
|
if (j >= patternSize)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
i += shift[j - 1];
|
||||||
|
j = Math.max(j - shift[j - 1], 0);
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] KnuthMorrisPrattShift(char[] pattern) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
|
||||||
|
int[] shift = new int[patternSize];
|
||||||
|
shift[0] = 1;
|
||||||
|
|
||||||
|
int i = 1, j = 0;
|
||||||
|
|
||||||
|
while ((i + j) < patternSize) {
|
||||||
|
if (pattern[i + j] == pattern[j]) {
|
||||||
|
shift[i + j] = i;
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
if (j == 0)
|
||||||
|
shift[i] = i + 1;
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
i = i + shift[j - 1];
|
||||||
|
j = Math.max(j - shift[j - 1], 0);
|
||||||
|
} else {
|
||||||
|
i = i + 1;
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int BoyerMooreHorspoolSimpleSearch(char[] pattern, char[] text) {
|
||||||
|
int patternSize = pattern.length;
|
||||||
|
int textSize = text.length;
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
while ((i + patternSize) <= textSize) {
|
||||||
|
j = patternSize - 1;
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j--;
|
||||||
|
if (j < 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int BoyerMooreHorspoolSearch(char[] pattern, char[] text) {
|
||||||
|
|
||||||
|
int shift[] = new int[256];
|
||||||
|
|
||||||
|
for (int k = 0; k < 256; k++) {
|
||||||
|
shift[k] = pattern.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < pattern.length - 1; k++) {
|
||||||
|
shift[pattern[k]] = pattern.length - 1 - k;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0, j = 0;
|
||||||
|
|
||||||
|
while ((i + pattern.length) <= text.length) {
|
||||||
|
j = pattern.length - 1;
|
||||||
|
|
||||||
|
while (text[i + j] == pattern[j]) {
|
||||||
|
j -= 1;
|
||||||
|
if (j < 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = i + shift[text[i + pattern.length - 1]];
|
||||||
|
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package algorithms;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
|
||||||
|
|
||||||
|
public class StringSearchAlgorithmsTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringSearchAlgorithms(){
|
||||||
|
String text = "This is some nice text.";
|
||||||
|
String pattern = "some";
|
||||||
|
|
||||||
|
int realPosition = text.indexOf(pattern);
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-1
@@ -1,9 +1,11 @@
|
|||||||
|
package algorithms.binarysearch;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import com.baeldung.algorithms.binarysearch.BinarySearch;
|
||||||
|
|
||||||
public class BinarySearchTest {
|
public class BinarySearchTest {
|
||||||
|
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionBruteForceTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionBruteForce.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionByFastAndSlowIteratorsTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionByFastAndSlowIteratorsTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleDetectionByHashingTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleDetectionByHashingTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_detectLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleDetectionByHashing.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
+62
@@ -0,0 +1,62 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
public class CycleDetectionTestBase {
|
||||||
|
|
||||||
|
@Parameters
|
||||||
|
public static Collection<Object[]> getLists() {
|
||||||
|
return Arrays.asList(new Object[][] {
|
||||||
|
{ createList(), false },
|
||||||
|
{ createListWithLoop(), true },
|
||||||
|
{ createListWithFullCycle(), true },
|
||||||
|
{ createListWithSingleNodeInCycle(), true }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createList() {
|
||||||
|
Node<Integer> root = Node.createNewNode(10, null);
|
||||||
|
|
||||||
|
for (int i = 9; i >= 1; --i) {
|
||||||
|
Node<Integer> current = Node.createNewNode(i, root);
|
||||||
|
root = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithLoop() {
|
||||||
|
Node<Integer> node = createList();
|
||||||
|
createLoop(node);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithFullCycle() {
|
||||||
|
Node<Integer> head = createList();
|
||||||
|
Node<Integer> tail = Node.getTail(head);
|
||||||
|
tail.next = head;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node<Integer> createListWithSingleNodeInCycle() {
|
||||||
|
Node<Integer> head = createList();
|
||||||
|
Node<Integer> tail = Node.getTail(head);
|
||||||
|
tail.next = tail;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createLoop(Node<Integer> root) {
|
||||||
|
Node<Integer> tail = Node.getTail(root);
|
||||||
|
|
||||||
|
Node<Integer> middle = root;
|
||||||
|
for (int i = 1; i <= 4; i++) {
|
||||||
|
middle = middle.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
tail.next = middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalBruteForceTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalBruteForceTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalBruteForce.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalByCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalByCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalByCountingLoopNodes.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
@RunWith(value = Parameterized.class)
|
||||||
|
public class CycleRemovalWithoutCountingLoopNodesTest extends CycleDetectionTestBase {
|
||||||
|
boolean cycleExists;
|
||||||
|
Node<Integer> head;
|
||||||
|
|
||||||
|
public CycleRemovalWithoutCountingLoopNodesTest(Node<Integer> head, boolean cycleExists) {
|
||||||
|
super();
|
||||||
|
this.cycleExists = cycleExists;
|
||||||
|
this.head = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenList_ifLoopExists_thenDetectAndRemoveLoop() {
|
||||||
|
Assert.assertEquals(cycleExists, CycleRemovalWithoutCountingLoopNodes.detectAndRemoveCycle(head));
|
||||||
|
Assert.assertFalse(CycleDetectionByFastAndSlowIterators.detectCycle(head).cycleExists);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>example-animal-sniffer-mvn-plugin</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>animal-sniffer-maven-plugin</artifactId>
|
||||||
|
<version>1.16</version>
|
||||||
|
<configuration>
|
||||||
|
<signature>
|
||||||
|
<groupId>org.codehaus.mojo.signature</groupId>
|
||||||
|
<artifactId>java16</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
</signature>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>animal-sniffer</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
//import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hello world!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
public static void main( String[] args )
|
||||||
|
{
|
||||||
|
System.out.println( "Hello World!" );
|
||||||
|
//System.out.println(StandardCharsets.UTF_8.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
|
||||||
|
assertTrue( true );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>apache-cayenne</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>apache-cayenne</name>
|
||||||
|
<description>Introduction to Apache Cayenne</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<mysql.connector.version>5.1.44</mysql.connector.version>
|
||||||
|
<cayenne.version>4.0.M5</cayenne.version>
|
||||||
|
<junit.version>4.12</junit.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.cayenne</groupId>
|
||||||
|
<artifactId>cayenne-server</artifactId>
|
||||||
|
<version>${cayenne.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>${mysql.connector.version}</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.cayenne.plugins</groupId>
|
||||||
|
<artifactId>cayenne-modeler-maven-plugin</artifactId>
|
||||||
|
<version>${cayenne.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.auto._Article;
|
||||||
|
|
||||||
|
public class Article extends _Article {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.auto._Author;
|
||||||
|
|
||||||
|
public class Author extends _Author {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent.auto;
|
||||||
|
|
||||||
|
import org.apache.cayenne.CayenneDataObject;
|
||||||
|
import org.apache.cayenne.exp.Property;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.Author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class _Article was generated by Cayenne.
|
||||||
|
* It is probably a good idea to avoid changing this class manually,
|
||||||
|
* since it may be overwritten next time code is regenerated.
|
||||||
|
* If you need to make any customizations, please use subclass.
|
||||||
|
*/
|
||||||
|
public abstract class _Article extends CayenneDataObject {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String ID_PK_COLUMN = "id";
|
||||||
|
|
||||||
|
public static final Property<String> CONTENT = Property.create("content", String.class);
|
||||||
|
public static final Property<String> TITLE = Property.create("title", String.class);
|
||||||
|
public static final Property<Author> AUTHOR = Property.create("author", Author.class);
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
writeProperty("content", content);
|
||||||
|
}
|
||||||
|
public String getContent() {
|
||||||
|
return (String)readProperty("content");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
writeProperty("title", title);
|
||||||
|
}
|
||||||
|
public String getTitle() {
|
||||||
|
return (String)readProperty("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthor(Author author) {
|
||||||
|
setToOneTarget("author", author, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Author getAuthor() {
|
||||||
|
return (Author)readProperty("author");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.baeldung.apachecayenne.persistent.auto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.cayenne.CayenneDataObject;
|
||||||
|
import org.apache.cayenne.exp.Property;
|
||||||
|
|
||||||
|
import com.baeldung.apachecayenne.persistent.Article;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class _Author was generated by Cayenne.
|
||||||
|
* It is probably a good idea to avoid changing this class manually,
|
||||||
|
* since it may be overwritten next time code is regenerated.
|
||||||
|
* If you need to make any customizations, please use subclass.
|
||||||
|
*/
|
||||||
|
public abstract class _Author extends CayenneDataObject {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final String ID_PK_COLUMN = "id";
|
||||||
|
|
||||||
|
public static final Property<String> NAME = Property.create("name", String.class);
|
||||||
|
public static final Property<List<Article>> ARTICLES = Property.create("articles", List.class);
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
writeProperty("name", name);
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return (String)readProperty("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToArticles(Article obj) {
|
||||||
|
addToManyTarget("articles", obj, true);
|
||||||
|
}
|
||||||
|
public void removeFromArticles(Article obj) {
|
||||||
|
removeToManyTarget("articles", obj, true);
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<Article> getArticles() {
|
||||||
|
return (List<Article>)readProperty("articles");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user