Merge branch 'master' of github.com:eugenp/tutorials

This commit is contained in:
Nick 2019-12-08 10:33:08 +00:00
commit a805787669
7100 changed files with 78775 additions and 194852 deletions

12
.gitignore vendored
View File

@ -4,6 +4,7 @@ bin/
*.class
# Package Files #
*.jar
*.war
*.ear
@ -29,7 +30,7 @@ out/
.DS_Store
# Maven
log/
log/*
target/
# Gradle
@ -82,4 +83,11 @@ jta/transaction-logs/
software-security/sql-injection-samples/derby.log
spring-soap/src/main/java/com/baeldung/springsoap/gen/
/report-*.json
transaction.log
transaction.log
*-shell.log
apache-cxf/cxf-aegis/baeldung.xml
apache-fop/src/test/resources/input.xml
apache-fop/src/test/resources/output_herold.pdf
apache-fop/src/test/resources/output_html2fo.pdf
apache-fop/src/test/resources/output_jtidy.pdf

View File

@ -1,3 +1,7 @@
## Relevant articles:
## Akka HTTP
This module contains articles about Akka HTTP.
### Relevant articles:
- [Introduction to Akka HTTP](https://www.baeldung.com/akka-http)

View File

@ -1,47 +1,46 @@
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>akka-http</artifactId>
<name>akka-http</name>
<modelVersion>4.0.0</modelVersion>
<artifactId>akka-http</artifactId>
<name>akka-http</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http_2.12</artifactId>
<version>${akka.http.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-stream_2.12</artifactId>
<version>${akka.stream.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-jackson_2.12</artifactId>
<version>${akka.http.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-testkit_2.12</artifactId>
<version>${akka.http.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http_2.12</artifactId>
<version>${akka.http.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-stream_2.12</artifactId>
<version>${akka.stream.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-jackson_2.12</artifactId>
<version>${akka.http.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-testkit_2.12</artifactId>
<version>${akka.http.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<akka.http.version>10.0.11</akka.http.version>
<akka.stream.version>2.5.11</akka.stream.version>
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<akka.http.version>10.0.11</akka.http.version>
<akka.stream.version>2.5.11</akka.stream.version>
</properties>
</project>

View File

@ -1,3 +1,7 @@
## Akka Streams
This module contains articles about Akka Streams.
### Relevant articles
- [Guide to Akka Streams](http://www.baeldung.com/akka-streams)
- [Guide to Akka Streams](https://www.baeldung.com/akka-streams)

View File

@ -1,13 +1,13 @@
<?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">
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>akka-streams</artifactId>
<name>akka-streams</name>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

View File

@ -1,6 +1,10 @@
## Relevant articles:
## Genetic Algorithms
- [Introduction to Jenetics Library](http://www.baeldung.com/jenetics)
- [Ant Colony Optimization](http://www.baeldung.com/java-ant-colony-optimization)
This module contains articles about genetic algorithms.
### Relevant articles:
- [Introduction to Jenetics Library](https://www.baeldung.com/jenetics)
- [Ant Colony Optimization](https://www.baeldung.com/java-ant-colony-optimization)
- [Design a Genetic Algorithm in Java](https://www.baeldung.com/java-genetic-algorithm)
- [The Traveling Salesman Problem in Java](https://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)

View File

@ -1,10 +1,11 @@
<?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">
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>algorithms-genetic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-genetic</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
@ -60,5 +61,4 @@
<commons-codec.version>1.11</commons-codec.version>
</properties>
</project>

View File

@ -1,4 +0,0 @@
/target/
.settings/
.classpath
.project

View File

@ -1,18 +1,13 @@
## Relevant articles:
## Algorithms - Miscellaneous
- [Validating Input With Finite Automata in Java](http://www.baeldung.com/java-finite-automata)
- [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)
- [Binary Search Algorithm in Java](http://www.baeldung.com/java-binary-search)
- [Introduction to Minimax Algorithm](http://www.baeldung.com/java-minimax-algorithm)
- [How to Calculate Levenshtein Distance in Java?](http://www.baeldung.com/java-levenshtein-distance)
- [How to Find the Kth Largest Element in Java](http://www.baeldung.com/java-kth-largest-element)
- [Multi-Swarm Optimization Algorithm in Java](http://www.baeldung.com/java-multi-swarm-algorithm)
- [String Search Algorithms for Large Texts](http://www.baeldung.com/java-full-text-search-algorithms)
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
- [Find the Middle Element of a Linked List](http://www.baeldung.com/java-linked-list-middle-element)
- [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial)
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
- [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm)
This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and
[genetic algorithms](/../algorithms-genetic), have their own dedicated modules.
### Relevant articles:
- [Validating Input With Finite Automata in Java](https://www.baeldung.com/java-finite-automata)
- [Example of Hill Climbing Algorithm](https://www.baeldung.com/java-hill-climbing-algorithm)
- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
- More articles: [[next -->]](/../algorithms-miscellaneous-2)

View File

@ -1,10 +1,11 @@
<?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">
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>algorithms-miscellaneous-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-miscellaneous-1</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
@ -43,7 +44,7 @@
<groupId>com.github.dpaukov</groupId>
<artifactId>combinatoricslib3</artifactId>
<version>${combinatoricslib3.version}</version>
</dependency>
</dependency>
</dependencies>
<build>

View File

@ -1,194 +0,0 @@
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;
}
}

View File

@ -1,25 +0,0 @@
package com.baeldung.algorithms;
import org.junit.Assert;
import org.junit.Test;
import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
public class StringSearchAlgorithmsUnitTest {
@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()));
}
}

View File

@ -1,4 +0,0 @@
/target/
.settings/
.classpath
.project

View File

@ -1,19 +1,16 @@
## Relevant articles:
## Algorithms - Miscellaneous
- [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra)
- [Introduction to Cobertura](http://www.baeldung.com/cobertura)
- [Test a Linked List for Cyclicity](http://www.baeldung.com/java-linked-list-cyclicity)
- [Introduction to JGraphT](http://www.baeldung.com/jgrapht)
- [A Maze Solver in Java](http://www.baeldung.com/java-solve-maze)
- [Create a Sudoku Solver in Java](http://www.baeldung.com/java-sudoku)
- [Displaying Money Amounts in Words](http://www.baeldung.com/java-money-into-words)
- [A Collaborative Filtering Recommendation System in Java](http://www.baeldung.com/java-collaborative-filtering-recommendations)
- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap)
- [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points)
- [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines)
- [Round Up to the Nearest Hundred](https://www.baeldung.com/java-round-up-nearest-hundred)
- [Calculate Percentage in Java](https://www.baeldung.com/java-calculate-percentage)
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
- [Convert Latitude and Longitude to a 2D Point in Java](https://www.baeldung.com/java-convert-latitude-longitude)
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and
[genetic algorithms](/../algorithms-genetic), have their own dedicated modules.
### Relevant articles:
- [Dijkstra Shortest Path Algorithm in Java](https://www.baeldung.com/java-dijkstra)
- [Introduction to Cobertura](https://www.baeldung.com/cobertura)
- [Test a Linked List for Cyclicity](https://www.baeldung.com/java-linked-list-cyclicity)
- [Introduction to JGraphT](https://www.baeldung.com/jgrapht)
- [A Maze Solver in Java](https://www.baeldung.com/java-solve-maze)
- [Create a Sudoku Solver in Java](https://www.baeldung.com/java-sudoku)
- [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words)
- [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations)
- More articles: [[<-- prev]](/../algorithms-miscellaneous-1) [[next -->]](/../algorithms-miscellaneous-3)

View File

@ -1,5 +1,6 @@
<?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">
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>algorithms-miscellaneous-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
@ -34,9 +35,9 @@
<version>${org.jgrapht.core.version}</version>
</dependency>
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-ext</artifactId>
<version>${org.jgrapht.ext.version}</version>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-ext</artifactId>
<version>${org.jgrapht.ext.version}</version>
</dependency>
<dependency>
<groupId>pl.allegro.finance</groupId>

View File

@ -0,0 +1,30 @@
package com.baeldung.algorithms.astar;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class Graph<T extends GraphNode> {
private final Set<T> nodes;
private final Map<String, Set<String>> connections;
public Graph(Set<T> nodes, Map<String, Set<String>> connections) {
this.nodes = nodes;
this.connections = connections;
}
public T getNode(String id) {
return nodes.stream()
.filter(node -> node.getId().equals(id))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No node found with ID"));
}
public Set<T> getConnections(T node) {
return connections.get(node.getId()).stream()
.map(this::getNode)
.collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.algorithms.astar;
public interface GraphNode {
String getId();
}

View File

@ -0,0 +1,66 @@
package com.baeldung.algorithms.astar;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.stream.Collectors;
public class RouteFinder<T extends GraphNode> {
private final Graph<T> graph;
private final Scorer<T> nextNodeScorer;
private final Scorer<T> targetScorer;
public RouteFinder(Graph<T> graph, Scorer<T> nextNodeScorer, Scorer<T> targetScorer) {
this.graph = graph;
this.nextNodeScorer = nextNodeScorer;
this.targetScorer = targetScorer;
}
public List<T> findRoute(T from, T to) {
Map<T, RouteNode<T>> allNodes = new HashMap<>();
Queue<RouteNode> openSet = new PriorityQueue<>();
RouteNode<T> start = new RouteNode<>(from, null, 0d, targetScorer.computeCost(from, to));
allNodes.put(from, start);
openSet.add(start);
while (!openSet.isEmpty()) {
System.out.println("Open Set contains: " + openSet.stream().map(RouteNode::getCurrent).collect(Collectors.toSet()));
RouteNode<T> next = openSet.poll();
System.out.println("Looking at node: " + next);
if (next.getCurrent().equals(to)) {
System.out.println("Found our destination!");
List<T> route = new ArrayList<>();
RouteNode<T> current = next;
do {
route.add(0, current.getCurrent());
current = allNodes.get(current.getPrevious());
} while (current != null);
System.out.println("Route: " + route);
return route;
}
graph.getConnections(next.getCurrent()).forEach(connection -> {
double newScore = next.getRouteScore() + nextNodeScorer.computeCost(next.getCurrent(), connection);
RouteNode<T> nextNode = allNodes.getOrDefault(connection, new RouteNode<>(connection));
allNodes.put(connection, nextNode);
if (nextNode.getRouteScore() > newScore) {
nextNode.setPrevious(next.getCurrent());
nextNode.setRouteScore(newScore);
nextNode.setEstimatedScore(newScore + targetScorer.computeCost(connection, to));
openSet.add(nextNode);
System.out.println("Found a better route to node: " + nextNode);
}
});
}
throw new IllegalStateException("No route found");
}
}

View File

@ -0,0 +1,67 @@
package com.baeldung.algorithms.astar;
import java.util.StringJoiner;
class RouteNode<T extends GraphNode> implements Comparable<RouteNode> {
private final T current;
private T previous;
private double routeScore;
private double estimatedScore;
RouteNode(T current) {
this(current, null, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
}
RouteNode(T current, T previous, double routeScore, double estimatedScore) {
this.current = current;
this.previous = previous;
this.routeScore = routeScore;
this.estimatedScore = estimatedScore;
}
T getCurrent() {
return current;
}
T getPrevious() {
return previous;
}
double getRouteScore() {
return routeScore;
}
double getEstimatedScore() {
return estimatedScore;
}
void setPrevious(T previous) {
this.previous = previous;
}
void setRouteScore(double routeScore) {
this.routeScore = routeScore;
}
void setEstimatedScore(double estimatedScore) {
this.estimatedScore = estimatedScore;
}
@Override
public int compareTo(RouteNode other) {
if (this.estimatedScore > other.estimatedScore) {
return 1;
} else if (this.estimatedScore < other.estimatedScore) {
return -1;
} else {
return 0;
}
}
@Override
public String toString() {
return new StringJoiner(", ", RouteNode.class.getSimpleName() + "[", "]").add("current=" + current)
.add("previous=" + previous).add("routeScore=" + routeScore).add("estimatedScore=" + estimatedScore)
.toString();
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.algorithms.astar;
public interface Scorer<T extends GraphNode> {
double computeCost(T from, T to);
}

View File

@ -0,0 +1,19 @@
package com.baeldung.algorithms.astar.underground;
import com.baeldung.algorithms.astar.Scorer;
public class HaversineScorer implements Scorer<Station> {
@Override
public double computeCost(Station from, Station to) {
double R = 6372.8; // In kilometers
double dLat = Math.toRadians(to.getLatitude() - from.getLatitude());
double dLon = Math.toRadians(to.getLongitude() - from.getLongitude());
double lat1 = Math.toRadians(from.getLatitude());
double lat2 = Math.toRadians(to.getLatitude());
double a = Math.pow(Math.sin(dLat / 2),2) + Math.pow(Math.sin(dLon / 2),2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
}

View File

@ -0,0 +1,643 @@
package com.baeldung.algorithms.astar.underground;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.baeldung.algorithms.astar.Graph;
import com.baeldung.algorithms.astar.RouteFinder;
import org.junit.Before;
import org.junit.Test;
public class RouteFinderIntegrationTest {
private Graph<Station> underground;
private RouteFinder<Station> routeFinder;
@Before
public void setUp() throws Exception {
Set<Station> stations = new HashSet<>();
Map<String, Set<String>> connections = new HashMap<>();
stations.add(new Station("1", "Acton Town", 51.5028, -0.2801));
stations.add(new Station("2", "Aldgate", 51.5143, -0.0755));
stations.add(new Station("3", "Aldgate East", 51.5154, -0.0726));
stations.add(new Station("4", "All Saints", 51.5107, -0.013));
stations.add(new Station("5", "Alperton", 51.5407, -0.2997));
stations.add(new Station("6", "Amersham", 51.6736, -0.607));
stations.add(new Station("7", "Angel", 51.5322, -0.1058));
stations.add(new Station("8", "Archway", 51.5653, -0.1353));
stations.add(new Station("9", "Arnos Grove", 51.6164, -0.1331));
stations.add(new Station("10", "Arsenal", 51.5586, -0.1059));
stations.add(new Station("11", "Baker Street", 51.5226, -0.1571));
stations.add(new Station("12", "Balham", 51.4431, -0.1525));
stations.add(new Station("13", "Bank", 51.5133, -0.0886));
stations.add(new Station("14", "Barbican", 51.5204, -0.0979));
stations.add(new Station("15", "Barking", 51.5396, 0.081));
stations.add(new Station("16", "Barkingside", 51.5856, 0.0887));
stations.add(new Station("17", "Barons Court", 51.4905, -0.2139));
stations.add(new Station("18", "Bayswater", 51.5121, -0.1879));
stations.add(new Station("19", "Beckton", 51.5148, 0.0613));
stations.add(new Station("20", "Beckton Park", 51.5087, 0.055));
stations.add(new Station("21", "Becontree", 51.5403, 0.127));
stations.add(new Station("22", "Belsize Park", 51.5504, -0.1642));
stations.add(new Station("23", "Bermondsey", 51.4979, -0.0637));
stations.add(new Station("24", "Bethnal Green", 51.527, -0.0549));
stations.add(new Station("25", "Blackfriars", 51.512, -0.1031));
stations.add(new Station("26", "Blackhorse Road", 51.5867, -0.0417));
stations.add(new Station("27", "Blackwall", 51.5079, -0.0066));
stations.add(new Station("28", "Bond Street", 51.5142, -0.1494));
stations.add(new Station("29", "Borough", 51.5011, -0.0943));
stations.add(new Station("30", "Boston Manor", 51.4956, -0.325));
stations.add(new Station("31", "Bounds Green", 51.6071, -0.1243));
stations.add(new Station("32", "Bow Church", 51.5273, -0.0208));
stations.add(new Station("33", "Bow Road", 51.5269, -0.0247));
stations.add(new Station("34", "Brent Cross", 51.5766, -0.2136));
stations.add(new Station("35", "Brixton", 51.4627, -0.1145));
stations.add(new Station("36", "Bromley-By-Bow", 51.5248, -0.0119));
stations.add(new Station("37", "Buckhurst Hill", 51.6266, 0.0471));
stations.add(new Station("38", "Burnt Oak", 51.6028, -0.2641));
stations.add(new Station("39", "Caledonian Road", 51.5481, -0.1188));
stations.add(new Station("40", "Camden Town", 51.5392, -0.1426));
stations.add(new Station("41", "Canada Water", 51.4982, -0.0502));
stations.add(new Station("42", "Canary Wharf", 51.5051, -0.0209));
stations.add(new Station("43", "Canning Town", 51.5147, 0.0082));
stations.add(new Station("44", "Cannon Street", 51.5113, -0.0904));
stations.add(new Station("45", "Canons Park", 51.6078, -0.2947));
stations.add(new Station("46", "Chalfont & Latimer", 51.6679, -0.561));
stations.add(new Station("47", "Chalk Farm", 51.5441, -0.1538));
stations.add(new Station("48", "Chancery Lane", 51.5185, -0.1111));
stations.add(new Station("49", "Charing Cross", 51.508, -0.1247));
stations.add(new Station("50", "Chesham", 51.7052, -0.611));
stations.add(new Station("51", "Chigwell", 51.6177, 0.0755));
stations.add(new Station("52", "Chiswick Park", 51.4946, -0.2678));
stations.add(new Station("53", "Chorleywood", 51.6543, -0.5183));
stations.add(new Station("54", "Clapham Common", 51.4618, -0.1384));
stations.add(new Station("55", "Clapham North", 51.4649, -0.1299));
stations.add(new Station("56", "Clapham South", 51.4527, -0.148));
stations.add(new Station("57", "Cockfosters", 51.6517, -0.1496));
stations.add(new Station("58", "Colindale", 51.5955, -0.2502));
stations.add(new Station("59", "Colliers Wood", 51.418, -0.1778));
stations.add(new Station("60", "Covent Garden", 51.5129, -0.1243));
stations.add(new Station("61", "Crossharbour & London Arena", 51.4957, -0.0144));
stations.add(new Station("62", "Croxley", 51.647, -0.4412));
stations.add(new Station("63", "Custom House", 51.5095, 0.0276));
stations.add(new Station("64", "Cutty Sark", 51.4827, -0.0096));
stations.add(new Station("65", "Cyprus", 51.5085, 0.064));
stations.add(new Station("66", "Dagenham East", 51.5443, 0.1655));
stations.add(new Station("67", "Dagenham Heathway", 51.5417, 0.1469));
stations.add(new Station("68", "Debden", 51.6455, 0.0838));
stations.add(new Station("69", "Deptford Bridge", 51.474, -0.0216));
stations.add(new Station("70", "Devons Road", 51.5223, -0.0173));
stations.add(new Station("71", "Dollis Hill", 51.552, -0.2387));
stations.add(new Station("72", "Ealing Broadway", 51.5152, -0.3017));
stations.add(new Station("73", "Ealing Common", 51.5101, -0.2882));
stations.add(new Station("74", "Earl's Court", 51.492, -0.1973));
stations.add(new Station("75", "Eastcote", 51.5765, -0.397));
stations.add(new Station("76", "East Acton", 51.5168, -0.2474));
stations.add(new Station("77", "East Finchley", 51.5874, -0.165));
stations.add(new Station("78", "East Ham", 51.5394, 0.0518));
stations.add(new Station("79", "East India", 51.5093, -0.0021));
stations.add(new Station("80", "East Putney", 51.4586, -0.2112));
stations.add(new Station("81", "Edgware", 51.6137, -0.275));
stations.add(new Station("82", "Edgware Road (B)", 51.5199, -0.1679));
stations.add(new Station("83", "Edgware Road (C)", 51.5203, -0.17));
stations.add(new Station("84", "Elephant & Castle", 51.4943, -0.1001));
stations.add(new Station("85", "Elm Park", 51.5496, 0.1977));
stations.add(new Station("86", "Elverson Road", 51.4693, -0.0174));
stations.add(new Station("87", "Embankment", 51.5074, -0.1223));
stations.add(new Station("88", "Epping", 51.6937, 0.1139));
stations.add(new Station("89", "Euston", 51.5282, -0.1337));
stations.add(new Station("90", "Euston Square", 51.526, -0.1359));
stations.add(new Station("91", "Fairlop", 51.596, 0.0912));
stations.add(new Station("92", "Farringdon", 51.5203, -0.1053));
stations.add(new Station("93", "Finchley Central", 51.6012, -0.1932));
stations.add(new Station("94", "Finchley Road", 51.5472, -0.1803));
stations.add(new Station("95", "Finsbury Park", 51.5642, -0.1065));
stations.add(new Station("96", "Fulham Broadway", 51.4804, -0.195));
stations.add(new Station("97", "Gallions Reach", 51.5096, 0.0716));
stations.add(new Station("98", "Gants Hill", 51.5765, 0.0663));
stations.add(new Station("99", "Gloucester Road", 51.4945, -0.1829));
stations.add(new Station("100", "Golders Green", 51.5724, -0.1941));
stations.add(new Station("101", "Goldhawk Road", 51.5018, -0.2267));
stations.add(new Station("102", "Goodge Street", 51.5205, -0.1347));
stations.add(new Station("103", "Grange Hill", 51.6132, 0.0923));
stations.add(new Station("104", "Great Portland Street", 51.5238, -0.1439));
stations.add(new Station("105", "Greenford", 51.5423, -0.3456));
stations.add(new Station("106", "Greenwich", 51.4781, -0.0149));
stations.add(new Station("107", "Green Park", 51.5067, -0.1428));
stations.add(new Station("108", "Gunnersbury", 51.4915, -0.2754));
stations.add(new Station("109", "Hainault", 51.603, 0.0933));
stations.add(new Station("110", "Hammersmith", 51.4936, -0.2251));
stations.add(new Station("111", "Hampstead", 51.5568, -0.178));
stations.add(new Station("112", "Hanger Lane", 51.5302, -0.2933));
stations.add(new Station("113", "Harlesden", 51.5362, -0.2575));
stations.add(new Station("114", "Harrow & Wealdston", 51.5925, -0.3351));
stations.add(new Station("115", "Harrow-on-the-Hill", 51.5793, -0.3366));
stations.add(new Station("116", "Hatton Cross", 51.4669, -0.4227));
stations.add(new Station("117", "Heathrow Terminals 1, 2 & 3", 51.4713, -0.4524));
stations.add(new Station("118", "Heathrow Terminal 4", 51.4598, -0.4476));
stations.add(new Station("119", "Hendon Central", 51.5829, -0.2259));
stations.add(new Station("120", "Heron Quays", 51.5033, -0.0215));
stations.add(new Station("121", "High Barnet", 51.6503, -0.1943));
stations.add(new Station("122", "High Street Kensington", 51.5009, -0.1925));
stations.add(new Station("123", "Highbury & Islington", 51.546, -0.104));
stations.add(new Station("124", "Highgate", 51.5777, -0.1458));
stations.add(new Station("125", "Hillingdon", 51.5538, -0.4499));
stations.add(new Station("126", "Holborn", 51.5174, -0.12));
stations.add(new Station("127", "Holland Park", 51.5075, -0.206));
stations.add(new Station("128", "Holloway Road", 51.5526, -0.1132));
stations.add(new Station("129", "Hornchurch", 51.5539, 0.2184));
stations.add(new Station("130", "Hounslow Central", 51.4713, -0.3665));
stations.add(new Station("131", "Hounslow East", 51.4733, -0.3564));
stations.add(new Station("132", "Hounslow West", 51.4734, -0.3855));
stations.add(new Station("133", "Hyde Park Corner", 51.5027, -0.1527));
stations.add(new Station("134", "Ickenham", 51.5619, -0.4421));
stations.add(new Station("135", "Island Gardens", 51.4871, -0.0101));
stations.add(new Station("136", "Kennington", 51.4884, -0.1053));
stations.add(new Station("137", "Kensal Green", 51.5304, -0.225));
stations.add(new Station("138", "Kensington (Olympia)", 51.4983, -0.2106));
stations.add(new Station("139", "Kentish Town", 51.5507, -0.1402));
stations.add(new Station("140", "Kenton", 51.5816, -0.3162));
stations.add(new Station("141", "Kew Gardens", 51.477, -0.285));
stations.add(new Station("142", "Kilburn", 51.5471, -0.2047));
stations.add(new Station("143", "Kilburn Park", 51.5351, -0.1939));
stations.add(new Station("144", "Kingsbury", 51.5846, -0.2786));
stations.add(new Station("145", "King's Cross St. Pancras", 51.5308, -0.1238));
stations.add(new Station("146", "Knightsbridge", 51.5015, -0.1607));
stations.add(new Station("147", "Ladbroke Grove", 51.5172, -0.2107));
stations.add(new Station("148", "Lambeth North", 51.4991, -0.1115));
stations.add(new Station("149", "Lancaster Gate", 51.5119, -0.1756));
stations.add(new Station("150", "Latimer Road", 51.5139, -0.2172));
stations.add(new Station("151", "Leicester Square", 51.5113, -0.1281));
stations.add(new Station("152", "Lewisham", 51.4657, -0.0142));
stations.add(new Station("153", "Leyton", 51.5566, -0.0053));
stations.add(new Station("154", "Leytonstone", 51.5683, 0.0083));
stations.add(new Station("155", "Limehouse", 51.5123, -0.0396));
stations.add(new Station("156", "Liverpool Street", 51.5178, -0.0823));
stations.add(new Station("157", "London Bridge", 51.5052, -0.0864));
stations.add(new Station("158", "Loughton", 51.6412, 0.0558));
stations.add(new Station("159", "Maida Vale", 51.53, -0.1854));
stations.add(new Station("160", "Manor House", 51.5712, -0.0958));
stations.add(new Station("161", "Mansion House", 51.5122, -0.094));
stations.add(new Station("162", "Marble Arch", 51.5136, -0.1586));
stations.add(new Station("163", "Marylebone", 51.5225, -0.1631));
stations.add(new Station("164", "Mile End", 51.5249, -0.0332));
stations.add(new Station("165", "Mill Hill East", 51.6082, -0.2103));
stations.add(new Station("166", "Monument", 51.5108, -0.0863));
stations.add(new Station("167", "Moorgate", 51.5186, -0.0886));
stations.add(new Station("168", "Moor Park", 51.6294, -0.432));
stations.add(new Station("169", "Morden", 51.4022, -0.1948));
stations.add(new Station("170", "Mornington Crescent", 51.5342, -0.1387));
stations.add(new Station("171", "Mudchute", 51.4902, -0.0145));
stations.add(new Station("172", "Neasden", 51.5542, -0.2503));
stations.add(new Station("173", "Newbury Park", 51.5756, 0.0899));
stations.add(new Station("174", "New Cross", 51.4767, -0.0327));
stations.add(new Station("175", "New Cross Gate", 51.4757, -0.0402));
stations.add(new Station("176", "Northfields", 51.4995, -0.3142));
stations.add(new Station("177", "Northolt", 51.5483, -0.3687));
stations.add(new Station("178", "Northwick Park", 51.5784, -0.3184));
stations.add(new Station("179", "Northwood", 51.6111, -0.424));
stations.add(new Station("180", "Northwood Hills", 51.6004, -0.4092));
stations.add(new Station("181", "North Acton", 51.5237, -0.2597));
stations.add(new Station("182", "North Ealing", 51.5175, -0.2887));
stations.add(new Station("183", "North Greenwich", 51.5005, 0.0039));
stations.add(new Station("184", "North Harrow", 51.5846, -0.3626));
stations.add(new Station("185", "North Wembley", 51.5621, -0.3034));
stations.add(new Station("186", "Notting Hill Gate", 51.5094, -0.1967));
stations.add(new Station("187", "Oakwood", 51.6476, -0.1318));
stations.add(new Station("188", "Old Street", 51.5263, -0.0873));
stations.add(new Station("189", "Osterley", 51.4813, -0.3522));
stations.add(new Station("190", "Oval", 51.4819, -0.113));
stations.add(new Station("191", "Oxford Circus", 51.515, -0.1415));
stations.add(new Station("192", "Paddington", 51.5154, -0.1755));
stations.add(new Station("193", "Park Royal", 51.527, -0.2841));
stations.add(new Station("194", "Parsons Green", 51.4753, -0.2011));
stations.add(new Station("195", "Perivale", 51.5366, -0.3232));
stations.add(new Station("196", "Picadilly Circus", 51.5098, -0.1342));
stations.add(new Station("197", "Pimlico", 51.4893, -0.1334));
stations.add(new Station("198", "Pinner", 51.5926, -0.3805));
stations.add(new Station("199", "Plaistow", 51.5313, 0.0172));
stations.add(new Station("200", "Poplar", 51.5077, -0.0173));
stations.add(new Station("201", "Preston Road", 51.572, -0.2954));
stations.add(new Station("202", "Prince Regent", 51.5093, 0.0336));
stations.add(new Station("203", "Pudding Mill Lane", 51.5343, -0.0139));
stations.add(new Station("204", "Putney Bridge", 51.4682, -0.2089));
stations.add(new Station("205", "Queen's Park", 51.5341, -0.2047));
stations.add(new Station("206", "Queensbury", 51.5942, -0.2861));
stations.add(new Station("207", "Queensway", 51.5107, -0.1877));
stations.add(new Station("208", "Ravenscourt Park", 51.4942, -0.2359));
stations.add(new Station("209", "Rayners Lane", 51.5753, -0.3714));
stations.add(new Station("210", "Redbridge", 51.5763, 0.0454));
stations.add(new Station("211", "Regent's Park", 51.5234, -0.1466));
stations.add(new Station("212", "Richmond", 51.4633, -0.3013));
stations.add(new Station("213", "Rickmansworth", 51.6404, -0.4733));
stations.add(new Station("214", "Roding Valley", 51.6171, 0.0439));
stations.add(new Station("215", "Rotherhithe", 51.501, -0.0525));
stations.add(new Station("216", "Royal Albert", 51.5084, 0.0465));
stations.add(new Station("217", "Royal Oak", 51.519, -0.188));
stations.add(new Station("218", "Royal Victoria", 51.5091, 0.0181));
stations.add(new Station("219", "Ruislip", 51.5715, -0.4213));
stations.add(new Station("220", "Ruislip Gardens", 51.5606, -0.4103));
stations.add(new Station("221", "Ruislip Manor", 51.5732, -0.4125));
stations.add(new Station("222", "Russell Square", 51.523, -0.1244));
stations.add(new Station("223", "Seven Sisters", 51.5822, -0.0749));
stations.add(new Station("224", "Shadwell", 51.5117, -0.056));
stations.add(new Station("225", "Shepherd's Bush (C)", 51.5046, -0.2187));
stations.add(new Station("226", "Shepherd's Bush (H)", 51.5058, -0.2265));
stations.add(new Station("227", "Shoreditch", 51.5227, -0.0708));
stations.add(new Station("228", "Sloane Square", 51.4924, -0.1565));
stations.add(new Station("229", "Snaresbrook", 51.5808, 0.0216));
stations.add(new Station("230", "Southfields", 51.4454, -0.2066));
stations.add(new Station("231", "Southgate", 51.6322, -0.128));
stations.add(new Station("232", "Southwark", 51.501, -0.1052));
stations.add(new Station("233", "South Ealing", 51.5011, -0.3072));
stations.add(new Station("234", "South Harrow", 51.5646, -0.3521));
stations.add(new Station("235", "South Kensington", 51.4941, -0.1738));
stations.add(new Station("236", "South Kenton", 51.5701, -0.3081));
stations.add(new Station("237", "South Quay", 51.5007, -0.0191));
stations.add(new Station("238", "South Ruislip", 51.5569, -0.3988));
stations.add(new Station("239", "South Wimbledon", 51.4154, -0.1919));
stations.add(new Station("240", "South Woodford", 51.5917, 0.0275));
stations.add(new Station("241", "Stamford Brook", 51.495, -0.2459));
stations.add(new Station("242", "Stanmore", 51.6194, -0.3028));
stations.add(new Station("243", "Stepney Green", 51.5221, -0.047));
stations.add(new Station("244", "Stockwell", 51.4723, -0.123));
stations.add(new Station("245", "Stonebridge Park", 51.5439, -0.2759));
stations.add(new Station("246", "Stratford", 51.5416, -0.0042));
stations.add(new Station("247", "St. James's Park", 51.4994, -0.1335));
stations.add(new Station("248", "St. John's Wood", 51.5347, -0.174));
stations.add(new Station("249", "St. Paul's", 51.5146, -0.0973));
stations.add(new Station("250", "Sudbury Hill", 51.5569, -0.3366));
stations.add(new Station("251", "Sudbury Town", 51.5507, -0.3156));
stations.add(new Station("252", "Surrey Quays", 51.4933, -0.0478));
stations.add(new Station("253", "Swiss Cottage", 51.5432, -0.1738));
stations.add(new Station("254", "Temple", 51.5111, -0.1141));
stations.add(new Station("255", "Theydon Bois", 51.6717, 0.1033));
stations.add(new Station("256", "Tooting Bec", 51.4361, -0.1598));
stations.add(new Station("257", "Tooting Broadway", 51.4275, -0.168));
stations.add(new Station("258", "Tottenham Court Road", 51.5165, -0.131));
stations.add(new Station("259", "Tottenham Hale", 51.5882, -0.0594));
stations.add(new Station("260", "Totteridge & Whetstone", 51.6302, -0.1791));
stations.add(new Station("261", "Tower Gateway", 51.5106, -0.0743));
stations.add(new Station("262", "Tower Hill", 51.5098, -0.0766));
stations.add(new Station("263", "Tufnell Park", 51.5567, -0.1374));
stations.add(new Station("264", "Turnham Green", 51.4951, -0.2547));
stations.add(new Station("265", "Turnpike Lane", 51.5904, -0.1028));
stations.add(new Station("266", "Upminster", 51.559, 0.251));
stations.add(new Station("267", "Upminster Bridge", 51.5582, 0.2343));
stations.add(new Station("268", "Upney", 51.5385, 0.1014));
stations.add(new Station("269", "Upton Park", 51.5352, 0.0343));
stations.add(new Station("270", "Uxbridge", 51.5463, -0.4786));
stations.add(new Station("271", "Vauxhall", 51.4861, -0.1253));
stations.add(new Station("272", "Victoria", 51.4965, -0.1447));
stations.add(new Station("273", "Walthamstow Central", 51.583, -0.0195));
stations.add(new Station("274", "Wanstead", 51.5775, 0.0288));
stations.add(new Station("275", "Wapping", 51.5043, -0.0558));
stations.add(new Station("276", "Warren Street", 51.5247, -0.1384));
stations.add(new Station("277", "Warwick Avenue", 51.5235, -0.1835));
stations.add(new Station("278", "Waterloo", 51.5036, -0.1143));
stations.add(new Station("279", "Watford", 51.6573, -0.4177));
stations.add(new Station("280", "Wembley Central", 51.5519, -0.2963));
stations.add(new Station("281", "Wembley Park", 51.5635, -0.2795));
stations.add(new Station("282", "Westbourne Park", 51.521, -0.2011));
stations.add(new Station("283", "Westferry", 51.5097, -0.0265));
stations.add(new Station("284", "Westminster", 51.501, -0.1254));
stations.add(new Station("285", "West Acton", 51.518, -0.2809));
stations.add(new Station("286", "West Brompton", 51.4872, -0.1953));
stations.add(new Station("287", "West Finchley", 51.6095, -0.1883));
stations.add(new Station("288", "West Ham", 51.5287, 0.0056));
stations.add(new Station("289", "West Hampstead", 51.5469, -0.1906));
stations.add(new Station("290", "West Harrow", 51.5795, -0.3533));
stations.add(new Station("291", "West India Quay", 51.507, -0.0203));
stations.add(new Station("292", "West Kensington", 51.4907, -0.2065));
stations.add(new Station("293", "West Ruislip", 51.5696, -0.4376));
stations.add(new Station("294", "Whitechapel", 51.5194, -0.0612));
stations.add(new Station("295", "White City", 51.512, -0.2239));
stations.add(new Station("296", "Willesden Green", 51.5492, -0.2215));
stations.add(new Station("297", "Willesden Junction", 51.5326, -0.2478));
stations.add(new Station("298", "Wimbledon", 51.4214, -0.2064));
stations.add(new Station("299", "Wimbledon Park", 51.4343, -0.1992));
stations.add(new Station("300", "Woodford", 51.607, 0.0341));
stations.add(new Station("301", "Woodside Park", 51.6179, -0.1856));
stations.add(new Station("302", "Wood Green", 51.5975, -0.1097));
connections.put("1", Stream.of("52","73","73","233","264").collect(Collectors.toSet()));
connections.put("2", Stream.of("156","262","156").collect(Collectors.toSet()));
connections.put("3", Stream.of("262","294","156","294").collect(Collectors.toSet()));
connections.put("4", Stream.of("70","200").collect(Collectors.toSet()));
connections.put("5", Stream.of("193","251").collect(Collectors.toSet()));
connections.put("6", Stream.of("46").collect(Collectors.toSet()));
connections.put("7", Stream.of("145","188").collect(Collectors.toSet()));
connections.put("8", Stream.of("124","263").collect(Collectors.toSet()));
connections.put("9", Stream.of("31","231").collect(Collectors.toSet()));
connections.put("10", Stream.of("95","128").collect(Collectors.toSet()));
connections.put("11", Stream.of("163","211","83","104","83","104","28","248","94","104").collect(Collectors.toSet()));
connections.put("12", Stream.of("56","256").collect(Collectors.toSet()));
connections.put("13", Stream.of("156","249","224","157","167","278").collect(Collectors.toSet()));
connections.put("14", Stream.of("92","167","92","167","92","167").collect(Collectors.toSet()));
connections.put("15", Stream.of("78","268","78").collect(Collectors.toSet()));
connections.put("16", Stream.of("91","173").collect(Collectors.toSet()));
connections.put("17", Stream.of("110","292","74","110").collect(Collectors.toSet()));
connections.put("18", Stream.of("186","192","186","192").collect(Collectors.toSet()));
connections.put("19", Stream.of("97").collect(Collectors.toSet()));
connections.put("20", Stream.of("65","216").collect(Collectors.toSet()));
connections.put("21", Stream.of("67","268").collect(Collectors.toSet()));
connections.put("22", Stream.of("47","111").collect(Collectors.toSet()));
connections.put("23", Stream.of("41","157").collect(Collectors.toSet()));
connections.put("24", Stream.of("156","164").collect(Collectors.toSet()));
connections.put("25", Stream.of("161","254","161","254").collect(Collectors.toSet()));
connections.put("26", Stream.of("259","273").collect(Collectors.toSet()));
connections.put("27", Stream.of("79","200").collect(Collectors.toSet()));
connections.put("28", Stream.of("162","191","11","107").collect(Collectors.toSet()));
connections.put("29", Stream.of("84","157").collect(Collectors.toSet()));
connections.put("30", Stream.of("176","189").collect(Collectors.toSet()));
connections.put("31", Stream.of("9","302").collect(Collectors.toSet()));
connections.put("32", Stream.of("70","203").collect(Collectors.toSet()));
connections.put("33", Stream.of("36","164","36","164").collect(Collectors.toSet()));
connections.put("34", Stream.of("100","119").collect(Collectors.toSet()));
connections.put("35", Stream.of("244").collect(Collectors.toSet()));
connections.put("36", Stream.of("33","288","33","288").collect(Collectors.toSet()));
connections.put("37", Stream.of("158","300").collect(Collectors.toSet()));
connections.put("38", Stream.of("58","81").collect(Collectors.toSet()));
connections.put("39", Stream.of("128","145").collect(Collectors.toSet()));
connections.put("40", Stream.of("47","89","139","170").collect(Collectors.toSet()));
connections.put("41", Stream.of("215","252","23","42").collect(Collectors.toSet()));
connections.put("42", Stream.of("120","291","41","183").collect(Collectors.toSet()));
connections.put("43", Stream.of("79","218","183","288").collect(Collectors.toSet()));
connections.put("44", Stream.of("161","166","161","166").collect(Collectors.toSet()));
connections.put("45", Stream.of("206","242").collect(Collectors.toSet()));
connections.put("46", Stream.of("6","50","53").collect(Collectors.toSet()));
connections.put("47", Stream.of("22","40").collect(Collectors.toSet()));
connections.put("48", Stream.of("126","249").collect(Collectors.toSet()));
connections.put("49", Stream.of("87","196","87","151").collect(Collectors.toSet()));
connections.put("50", Stream.of("46").collect(Collectors.toSet()));
connections.put("51", Stream.of("103","214").collect(Collectors.toSet()));
connections.put("52", Stream.of("1","264").collect(Collectors.toSet()));
connections.put("53", Stream.of("46","213").collect(Collectors.toSet()));
connections.put("54", Stream.of("55","56").collect(Collectors.toSet()));
connections.put("55", Stream.of("54","244").collect(Collectors.toSet()));
connections.put("56", Stream.of("12","54").collect(Collectors.toSet()));
connections.put("57", Stream.of("187").collect(Collectors.toSet()));
connections.put("58", Stream.of("38","119").collect(Collectors.toSet()));
connections.put("59", Stream.of("239","257").collect(Collectors.toSet()));
connections.put("60", Stream.of("126","151").collect(Collectors.toSet()));
connections.put("61", Stream.of("171","237").collect(Collectors.toSet()));
connections.put("62", Stream.of("168","279").collect(Collectors.toSet()));
connections.put("63", Stream.of("202","218").collect(Collectors.toSet()));
connections.put("64", Stream.of("106","135").collect(Collectors.toSet()));
connections.put("65", Stream.of("20","97").collect(Collectors.toSet()));
connections.put("66", Stream.of("67","85").collect(Collectors.toSet()));
connections.put("67", Stream.of("21","66").collect(Collectors.toSet()));
connections.put("68", Stream.of("158","255").collect(Collectors.toSet()));
connections.put("69", Stream.of("86","106").collect(Collectors.toSet()));
connections.put("70", Stream.of("4","32").collect(Collectors.toSet()));
connections.put("71", Stream.of("172","296").collect(Collectors.toSet()));
connections.put("72", Stream.of("285","73").collect(Collectors.toSet()));
connections.put("73", Stream.of("72","1","1","182").collect(Collectors.toSet()));
connections.put("74", Stream.of("99","122","138","286","292","17","99").collect(Collectors.toSet()));
connections.put("75", Stream.of("209","221","209","221").collect(Collectors.toSet()));
connections.put("76", Stream.of("181","295").collect(Collectors.toSet()));
connections.put("77", Stream.of("93","124").collect(Collectors.toSet()));
connections.put("78", Stream.of("15","269","15","269").collect(Collectors.toSet()));
connections.put("79", Stream.of("27","43").collect(Collectors.toSet()));
connections.put("80", Stream.of("204","230").collect(Collectors.toSet()));
connections.put("81", Stream.of("38").collect(Collectors.toSet()));
connections.put("82", Stream.of("163","192").collect(Collectors.toSet()));
connections.put("83", Stream.of("11","192","192","11","192").collect(Collectors.toSet()));
connections.put("84", Stream.of("148","29","136").collect(Collectors.toSet()));
connections.put("85", Stream.of("66","129").collect(Collectors.toSet()));
connections.put("86", Stream.of("69","152").collect(Collectors.toSet()));
connections.put("87", Stream.of("49","278","254","284","254","284","49","278").collect(Collectors.toSet()));
connections.put("88", Stream.of("255").collect(Collectors.toSet()));
connections.put("89", Stream.of("40","145","170","276","145","276").collect(Collectors.toSet()));
connections.put("90", Stream.of("104","145","104","145","104","145").collect(Collectors.toSet()));
connections.put("91", Stream.of("16","109").collect(Collectors.toSet()));
connections.put("92", Stream.of("14","145","14","145","14","145").collect(Collectors.toSet()));
connections.put("93", Stream.of("77","165","287").collect(Collectors.toSet()));
connections.put("94", Stream.of("253","289","11","281").collect(Collectors.toSet()));
connections.put("95", Stream.of("10","160","123","223").collect(Collectors.toSet()));
connections.put("96", Stream.of("194","286").collect(Collectors.toSet()));
connections.put("97", Stream.of("19","65").collect(Collectors.toSet()));
connections.put("98", Stream.of("173","210").collect(Collectors.toSet()));
connections.put("99", Stream.of("122","235","74","235","74","235").collect(Collectors.toSet()));
connections.put("100", Stream.of("34","111").collect(Collectors.toSet()));
connections.put("101", Stream.of("110","226").collect(Collectors.toSet()));
connections.put("102", Stream.of("258","276").collect(Collectors.toSet()));
connections.put("103", Stream.of("51","109").collect(Collectors.toSet()));
connections.put("104", Stream.of("11","90","11","90","11","90").collect(Collectors.toSet()));
connections.put("105", Stream.of("177","195").collect(Collectors.toSet()));
connections.put("106", Stream.of("64","69").collect(Collectors.toSet()));
connections.put("107", Stream.of("28","284","133","196","191","272").collect(Collectors.toSet()));
connections.put("108", Stream.of("141","264").collect(Collectors.toSet()));
connections.put("109", Stream.of("91","103").collect(Collectors.toSet()));
connections.put("110", Stream.of("17","208","101","17","264").collect(Collectors.toSet()));
connections.put("111", Stream.of("22","100").collect(Collectors.toSet()));
connections.put("112", Stream.of("181","195").collect(Collectors.toSet()));
connections.put("113", Stream.of("245","297").collect(Collectors.toSet()));
connections.put("114", Stream.of("140").collect(Collectors.toSet()));
connections.put("115", Stream.of("178","184","290").collect(Collectors.toSet()));
connections.put("116", Stream.of("117","118","132").collect(Collectors.toSet()));
connections.put("117", Stream.of("116","118").collect(Collectors.toSet()));
connections.put("118", Stream.of("116","117").collect(Collectors.toSet()));
connections.put("119", Stream.of("34","58").collect(Collectors.toSet()));
connections.put("120", Stream.of("42","237").collect(Collectors.toSet()));
connections.put("121", Stream.of("260").collect(Collectors.toSet()));
connections.put("122", Stream.of("99","186","74","186").collect(Collectors.toSet()));
connections.put("123", Stream.of("95","145").collect(Collectors.toSet()));
connections.put("124", Stream.of("8","77").collect(Collectors.toSet()));
connections.put("125", Stream.of("134","270","134","270").collect(Collectors.toSet()));
connections.put("126", Stream.of("48","258","60","222").collect(Collectors.toSet()));
connections.put("127", Stream.of("186","225").collect(Collectors.toSet()));
connections.put("128", Stream.of("10","39").collect(Collectors.toSet()));
connections.put("129", Stream.of("85","267").collect(Collectors.toSet()));
connections.put("130", Stream.of("131","132").collect(Collectors.toSet()));
connections.put("131", Stream.of("130","189").collect(Collectors.toSet()));
connections.put("132", Stream.of("116","130").collect(Collectors.toSet()));
connections.put("133", Stream.of("107","146").collect(Collectors.toSet()));
connections.put("134", Stream.of("125","219","125","219").collect(Collectors.toSet()));
connections.put("135", Stream.of("64","171").collect(Collectors.toSet()));
connections.put("136", Stream.of("84","190","278").collect(Collectors.toSet()));
connections.put("137", Stream.of("205","297").collect(Collectors.toSet()));
connections.put("138", Stream.of("74").collect(Collectors.toSet()));
connections.put("139", Stream.of("40","263").collect(Collectors.toSet()));
connections.put("140", Stream.of("114","236").collect(Collectors.toSet()));
connections.put("141", Stream.of("108","212").collect(Collectors.toSet()));
connections.put("142", Stream.of("289","296").collect(Collectors.toSet()));
connections.put("143", Stream.of("159","205").collect(Collectors.toSet()));
connections.put("144", Stream.of("206","281").collect(Collectors.toSet()));
connections.put("145", Stream.of("90","92","90","92","90","92","7","89","39","222","89","123").collect(Collectors.toSet()));
connections.put("146", Stream.of("133","235").collect(Collectors.toSet()));
connections.put("147", Stream.of("150","282").collect(Collectors.toSet()));
connections.put("148", Stream.of("84","278").collect(Collectors.toSet()));
connections.put("149", Stream.of("162","207").collect(Collectors.toSet()));
connections.put("150", Stream.of("147","226").collect(Collectors.toSet()));
connections.put("151", Stream.of("49","258","60","196").collect(Collectors.toSet()));
connections.put("152", Stream.of("86").collect(Collectors.toSet()));
connections.put("153", Stream.of("154","246").collect(Collectors.toSet()));
connections.put("154", Stream.of("153","229","274").collect(Collectors.toSet()));
connections.put("155", Stream.of("224","283").collect(Collectors.toSet()));
connections.put("156", Stream.of("13","24","2","167","3","167","2","167").collect(Collectors.toSet()));
connections.put("157", Stream.of("23","232","13","29").collect(Collectors.toSet()));
connections.put("158", Stream.of("37","68").collect(Collectors.toSet()));
connections.put("159", Stream.of("143","277").collect(Collectors.toSet()));
connections.put("160", Stream.of("95","265").collect(Collectors.toSet()));
connections.put("161", Stream.of("25","44","25","44").collect(Collectors.toSet()));
connections.put("162", Stream.of("28","149").collect(Collectors.toSet()));
connections.put("163", Stream.of("11","82").collect(Collectors.toSet()));
connections.put("164", Stream.of("24","246","33","243","33","243").collect(Collectors.toSet()));
connections.put("165", Stream.of("93").collect(Collectors.toSet()));
connections.put("166", Stream.of("44","262","44","262").collect(Collectors.toSet()));
connections.put("167", Stream.of("14","156","14","156","14","156","13","188").collect(Collectors.toSet()));
connections.put("168", Stream.of("62","179","213").collect(Collectors.toSet()));
connections.put("169", Stream.of("239").collect(Collectors.toSet()));
connections.put("170", Stream.of("40","89").collect(Collectors.toSet()));
connections.put("171", Stream.of("61","135").collect(Collectors.toSet()));
connections.put("172", Stream.of("71","281").collect(Collectors.toSet()));
connections.put("173", Stream.of("16","98").collect(Collectors.toSet()));
connections.put("174", Stream.of("252").collect(Collectors.toSet()));
connections.put("175", Stream.of("252").collect(Collectors.toSet()));
connections.put("176", Stream.of("30","233").collect(Collectors.toSet()));
connections.put("177", Stream.of("105","238").collect(Collectors.toSet()));
connections.put("178", Stream.of("115","201").collect(Collectors.toSet()));
connections.put("179", Stream.of("168","180").collect(Collectors.toSet()));
connections.put("180", Stream.of("179","198").collect(Collectors.toSet()));
connections.put("181", Stream.of("76","112","285").collect(Collectors.toSet()));
connections.put("182", Stream.of("73","193").collect(Collectors.toSet()));
connections.put("183", Stream.of("42","43").collect(Collectors.toSet()));
connections.put("184", Stream.of("115","198").collect(Collectors.toSet()));
connections.put("185", Stream.of("236","280").collect(Collectors.toSet()));
connections.put("186", Stream.of("127","207","18","122","18","122").collect(Collectors.toSet()));
connections.put("187", Stream.of("57","231").collect(Collectors.toSet()));
connections.put("188", Stream.of("7","167").collect(Collectors.toSet()));
connections.put("189", Stream.of("30","131").collect(Collectors.toSet()));
connections.put("190", Stream.of("136","244").collect(Collectors.toSet()));
connections.put("191", Stream.of("196","211","28","258","107","276").collect(Collectors.toSet()));
connections.put("192", Stream.of("82","277","18","83","18","83","83","217").collect(Collectors.toSet()));
connections.put("193", Stream.of("5","182").collect(Collectors.toSet()));
connections.put("194", Stream.of("96","204").collect(Collectors.toSet()));
connections.put("195", Stream.of("105","112").collect(Collectors.toSet()));
connections.put("196", Stream.of("49","191","107","151").collect(Collectors.toSet()));
connections.put("197", Stream.of("271","272").collect(Collectors.toSet()));
connections.put("198", Stream.of("180","184").collect(Collectors.toSet()));
connections.put("199", Stream.of("269","288","269","288").collect(Collectors.toSet()));
connections.put("200", Stream.of("4","27","283","291").collect(Collectors.toSet()));
connections.put("201", Stream.of("178","281").collect(Collectors.toSet()));
connections.put("202", Stream.of("63","216").collect(Collectors.toSet()));
connections.put("203", Stream.of("32","246").collect(Collectors.toSet()));
connections.put("204", Stream.of("80","194").collect(Collectors.toSet()));
connections.put("205", Stream.of("137","143").collect(Collectors.toSet()));
connections.put("206", Stream.of("45","144").collect(Collectors.toSet()));
connections.put("207", Stream.of("149","186").collect(Collectors.toSet()));
connections.put("208", Stream.of("110","241").collect(Collectors.toSet()));
connections.put("209", Stream.of("75","290","75","234").collect(Collectors.toSet()));
connections.put("210", Stream.of("98","274").collect(Collectors.toSet()));
connections.put("211", Stream.of("11","191").collect(Collectors.toSet()));
connections.put("212", Stream.of("141").collect(Collectors.toSet()));
connections.put("213", Stream.of("53","168").collect(Collectors.toSet()));
connections.put("214", Stream.of("51","300").collect(Collectors.toSet()));
connections.put("215", Stream.of("41","275").collect(Collectors.toSet()));
connections.put("216", Stream.of("20","202").collect(Collectors.toSet()));
connections.put("217", Stream.of("192","282").collect(Collectors.toSet()));
connections.put("218", Stream.of("43","63").collect(Collectors.toSet()));
connections.put("219", Stream.of("134","221","134","221").collect(Collectors.toSet()));
connections.put("220", Stream.of("238","293").collect(Collectors.toSet()));
connections.put("221", Stream.of("75","219","75","219").collect(Collectors.toSet()));
connections.put("222", Stream.of("126","145").collect(Collectors.toSet()));
connections.put("223", Stream.of("95","259").collect(Collectors.toSet()));
connections.put("224", Stream.of("13","155","261","275","294").collect(Collectors.toSet()));
connections.put("225", Stream.of("127","295").collect(Collectors.toSet()));
connections.put("226", Stream.of("101","150").collect(Collectors.toSet()));
connections.put("227", Stream.of("294").collect(Collectors.toSet()));
connections.put("228", Stream.of("235","272","235","272").collect(Collectors.toSet()));
connections.put("229", Stream.of("154","240").collect(Collectors.toSet()));
connections.put("230", Stream.of("80","299").collect(Collectors.toSet()));
connections.put("231", Stream.of("9","187").collect(Collectors.toSet()));
connections.put("232", Stream.of("157","278").collect(Collectors.toSet()));
connections.put("233", Stream.of("1","176").collect(Collectors.toSet()));
connections.put("234", Stream.of("209","250").collect(Collectors.toSet()));
connections.put("235", Stream.of("99","228","99","228","99","146").collect(Collectors.toSet()));
connections.put("236", Stream.of("140","185").collect(Collectors.toSet()));
connections.put("237", Stream.of("61","120").collect(Collectors.toSet()));
connections.put("238", Stream.of("177","220").collect(Collectors.toSet()));
connections.put("239", Stream.of("59","169").collect(Collectors.toSet()));
connections.put("240", Stream.of("229","300").collect(Collectors.toSet()));
connections.put("241", Stream.of("208","264").collect(Collectors.toSet()));
connections.put("242", Stream.of("45").collect(Collectors.toSet()));
connections.put("243", Stream.of("164","294","164","294").collect(Collectors.toSet()));
connections.put("244", Stream.of("55","190","35","271").collect(Collectors.toSet()));
connections.put("245", Stream.of("113","280").collect(Collectors.toSet()));
connections.put("246", Stream.of("153","164","203","288").collect(Collectors.toSet()));
connections.put("247", Stream.of("272","284","272","284").collect(Collectors.toSet()));
connections.put("248", Stream.of("11","253").collect(Collectors.toSet()));
connections.put("249", Stream.of("13","48").collect(Collectors.toSet()));
connections.put("250", Stream.of("234","251").collect(Collectors.toSet()));
connections.put("251", Stream.of("5","250").collect(Collectors.toSet()));
connections.put("252", Stream.of("41","174","175").collect(Collectors.toSet()));
connections.put("253", Stream.of("94","248").collect(Collectors.toSet()));
connections.put("254", Stream.of("25","87","25","87").collect(Collectors.toSet()));
connections.put("255", Stream.of("68","88").collect(Collectors.toSet()));
connections.put("256", Stream.of("12","257").collect(Collectors.toSet()));
connections.put("257", Stream.of("59","256").collect(Collectors.toSet()));
connections.put("258", Stream.of("126","191","102","151").collect(Collectors.toSet()));
connections.put("259", Stream.of("26","223").collect(Collectors.toSet()));
connections.put("260", Stream.of("121","301").collect(Collectors.toSet()));
connections.put("261", Stream.of("224").collect(Collectors.toSet()));
connections.put("262", Stream.of("2","166","3","166").collect(Collectors.toSet()));
connections.put("263", Stream.of("8","139").collect(Collectors.toSet()));
connections.put("264", Stream.of("52","108","241","1","110").collect(Collectors.toSet()));
connections.put("265", Stream.of("160","302").collect(Collectors.toSet()));
connections.put("266", Stream.of("267").collect(Collectors.toSet()));
connections.put("267", Stream.of("129","266").collect(Collectors.toSet()));
connections.put("268", Stream.of("15","21").collect(Collectors.toSet()));
connections.put("269", Stream.of("78","199","78","199").collect(Collectors.toSet()));
connections.put("270", Stream.of("125","125").collect(Collectors.toSet()));
connections.put("271", Stream.of("197","244").collect(Collectors.toSet()));
connections.put("272", Stream.of("228","247","228","247","107","197").collect(Collectors.toSet()));
connections.put("273", Stream.of("26").collect(Collectors.toSet()));
connections.put("274", Stream.of("154","210").collect(Collectors.toSet()));
connections.put("275", Stream.of("215","224").collect(Collectors.toSet()));
connections.put("276", Stream.of("89","102","89","191").collect(Collectors.toSet()));
connections.put("277", Stream.of("159","192").collect(Collectors.toSet()));
connections.put("278", Stream.of("87","148","232","284","87","136","13").collect(Collectors.toSet()));
connections.put("279", Stream.of("62").collect(Collectors.toSet()));
connections.put("280", Stream.of("185","245").collect(Collectors.toSet()));
connections.put("281", Stream.of("144","172","94","201").collect(Collectors.toSet()));
connections.put("282", Stream.of("147","217").collect(Collectors.toSet()));
connections.put("283", Stream.of("155","200","291").collect(Collectors.toSet()));
connections.put("284", Stream.of("87","247","87","247","107","278").collect(Collectors.toSet()));
connections.put("285", Stream.of("72","181").collect(Collectors.toSet()));
connections.put("286", Stream.of("74","96").collect(Collectors.toSet()));
connections.put("287", Stream.of("93","301").collect(Collectors.toSet()));
connections.put("288", Stream.of("36","199","36","199","43","246").collect(Collectors.toSet()));
connections.put("289", Stream.of("94","142").collect(Collectors.toSet()));
connections.put("290", Stream.of("115","209").collect(Collectors.toSet()));
connections.put("291", Stream.of("42","200","283").collect(Collectors.toSet()));
connections.put("292", Stream.of("17","74").collect(Collectors.toSet()));
connections.put("293", Stream.of("220").collect(Collectors.toSet()));
connections.put("294", Stream.of("3","243","224","227","3","243").collect(Collectors.toSet()));
connections.put("295", Stream.of("76","225").collect(Collectors.toSet()));
connections.put("296", Stream.of("71","142").collect(Collectors.toSet()));
connections.put("297", Stream.of("113","137").collect(Collectors.toSet()));
connections.put("298", Stream.of("299").collect(Collectors.toSet()));
connections.put("299", Stream.of("230","298").collect(Collectors.toSet()));
connections.put("300", Stream.of("37","214","240").collect(Collectors.toSet()));
connections.put("301", Stream.of("260","287").collect(Collectors.toSet()));
connections.put("302", Stream.of("31","265").collect(Collectors.toSet()));
underground = new Graph<>(stations, connections);
routeFinder = new RouteFinder<>(underground, new HaversineScorer(), new HaversineScorer());
}
@Test
public void findRoute() {
List<Station> route = routeFinder.findRoute(underground.getNode("74"), underground.getNode("7"));
System.out.println(route.stream().map(Station::getName).collect(Collectors.toList()));
}
}

View File

@ -0,0 +1,42 @@
package com.baeldung.algorithms.astar.underground;
import java.util.StringJoiner;
import com.baeldung.algorithms.astar.GraphNode;
public class Station implements GraphNode {
private final String id;
private final String name;
private final double latitude;
private final double longitude;
public Station(String id, String name, double latitude, double longitude) {
this.id = id;
this.name = name;
this.latitude = latitude;
this.longitude = longitude;
}
@Override
public String getId() {
return id;
}
public String getName() {
return name;
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
@Override
public String toString() {
return new StringJoiner(", ", Station.class.getSimpleName() + "[", "]").add("id='" + id + "'")
.add("name='" + name + "'").add("latitude=" + latitude).add("longitude=" + longitude).toString();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,10 +1,19 @@
## Algorithms - Miscellaneous
This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/algorithms-sorting) and
[genetic algorithms](/algorithms-genetic), have their own dedicated modules.
## Relevant Articles:
- [Java Two Pointer Technique](https://www.baeldung.com/java-two-pointer-technique)
- [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine)
- [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic)
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
- [Converting Between Roman and Arabic Numerals in Java](https://www.baeldung.com/java-convert-roman-arabic)
- [Practical Java Examples of the Big O Notation](https://www.baeldung.com/java-algorithm-complexity)
- [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted)
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
- [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation)
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)

View File

@ -1,3 +1,4 @@
<?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>
@ -54,6 +55,21 @@
<version>1.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh-core.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh-generator.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-bytecode</artifactId>
<version>${jmh-generator.version}</version>
</dependency>
</dependencies>
<build>
@ -73,5 +89,8 @@
<commons-collections4.version>4.3</commons-collections4.version>
<guava.version>28.0-jre</guava.version>
<retrofit.version>2.6.0</retrofit.version>
<jmh-core.version>1.19</jmh-core.version>
<jmh-generator.version>1.19</jmh-generator.version>
</properties>
</project>

View File

@ -0,0 +1,14 @@
## Algorithms - Miscellaneous
This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](https://github.com/eugenp/tutorials/blob/algorithms-sorting) and [genetic algorithms](https://github.com/eugenp/tutorials/blob/algorithms-genetic), have their own dedicated modules.
### Relevant articles:
- [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm)
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
- [Find the Middle Element of a Linked List](https://www.baeldung.com/java-linked-list-middle-element)
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters)
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
- [Find the Smallest Missing Integer in an Array](https://www.baeldung.com/java-smallest-missing-integer-in-array)
- More articles: [[<-- prev]](/algorithms-miscellaneous-3) [[next -->]](/algorithms-miscellaneous-5)

View File

@ -0,0 +1,52 @@
<?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>algorithms-miscellaneous-4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-miscellaneous-4</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${org.assertj.core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<properties>
<org.assertj.core.version>3.9.0</org.assertj.core.version>
<guava.version>27.0.1-jre</guava.version>
</properties>
</project>

View File

@ -0,0 +1,37 @@
package com.baeldung.algorithms.smallestinteger;
import java.util.Arrays;
public class SmallestMissingPositiveInteger {
public static int searchInSortedArray(int[] input) {
for (int i = 0; i < input.length; i++) {
if (i != input[i]) {
return i;
}
}
return input.length;
}
public static int searchInUnsortedArraySortingFirst(int[] input) {
Arrays.sort(input);
return searchInSortedArray(input);
}
public static int searchInUnsortedArrayBooleanArray(int[] input) {
boolean[] flags = new boolean[input.length];
for (int number : input) {
if (number < flags.length) {
flags[number] = true;
}
}
for (int i = 0; i < flags.length; i++) {
if (!flags[i]) {
return i;
}
}
return flags.length;
}
}

View File

@ -0,0 +1,97 @@
package com.baeldung.algorithms.smallestinteger;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class SmallestMissingPositiveIntegerUnitTest {
@Test
void givenArrayWithThreeMissing_whenSearchInSortedArray_thenThree() {
int[] input = new int[] {0, 1, 2, 4, 5};
int result = SmallestMissingPositiveInteger.searchInSortedArray(input);
assertThat(result).isEqualTo(3);
}
@Test
void givenArrayWithOneAndThreeMissing_whenSearchInSortedArray_thenOne() {
int[] input = new int[] {0, 2, 4, 5};
int result = SmallestMissingPositiveInteger.searchInSortedArray(input);
assertThat(result).isEqualTo(1);
}
@Test
void givenArrayWithoutMissingInteger_whenSearchInSortedArray_thenArrayLength() {
int[] input = new int[] {0, 1, 2, 3, 4, 5};
int result = SmallestMissingPositiveInteger.searchInSortedArray(input);
assertThat(result).isEqualTo(input.length);
}
@Test
void givenArrayWithThreeMissing_whenSearchInUnsortedArraySortingFirst_thenThree() {
int[] input = new int[] {1, 4, 0, 5, 2};
int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input);
assertThat(result).isEqualTo(3);
}
@Test
void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArraySortingFirst_thenOne() {
int[] input = new int[] {4, 2, 0, 5};
int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input);
assertThat(result).isEqualTo(1);
}
@Test
void givenArrayWithoutMissingInteger_whenSearchInUnsortedArraySortingFirst_thenArrayLength() {
int[] input = new int[] {4, 5, 1, 3, 0, 2};
int result = SmallestMissingPositiveInteger.searchInUnsortedArraySortingFirst(input);
assertThat(result).isEqualTo(input.length);
}
@Test
void givenArrayWithThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenThree() {
int[] input = new int[] {1, 4, 0, 5, 2};
int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input);
assertThat(result).isEqualTo(3);
}
@Test
void givenArrayWithOneAndThreeMissing_whenSearchInUnsortedArrayBooleanArray_thenOne() {
int[] input = new int[] {4, 2, 0, 5};
int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input);
assertThat(result).isEqualTo(1);
}
@Test
void givenArrayWithoutMissingInteger_whenSearchInUnsortedArrayBooleanArray_thenArrayLength() {
int[] input = new int[] {4, 5, 1, 3, 0, 2};
int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input);
assertThat(result).isEqualTo(input.length);
}
@Test
void givenArrayWithoutZero_whenSearchInUnsortedArrayBooleanArray_thenZero() {
int[] input = new int[] {11, 13, 14, 15};
int result = SmallestMissingPositiveInteger.searchInUnsortedArrayBooleanArray(input);
assertThat(result).isEqualTo(0);
}
}

View File

@ -0,0 +1,13 @@
## Algorithms - Miscellaneous
This module contains articles about algorithms. Some classes of algorithms, e.g., [sorting](/../algorithms-sorting) and
[genetic algorithms](/../algorithms-genetic), have their own dedicated modules.
### Relevant articles:
- [Converting Between Byte Arrays and Hexadecimal Strings in Java](https://www.baeldung.com/java-byte-arrays-hex-strings)
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
- [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack)
- [How to Determine if a Binary Tree is Balanced](https://www.baeldung.com/java-balanced-binary-tree)
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)

View File

@ -0,0 +1,65 @@
<?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>algorithms-miscellaneous-5</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-miscellaneous-5</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>pl.allegro.finance</groupId>
<artifactId>tradukisto</artifactId>
<version>${tradukisto.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${org.assertj.core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<properties>
<tradukisto.version>1.0.1</tradukisto.version>
<org.assertj.core.version>3.9.0</org.assertj.core.version>
<commons-codec.version>1.11</commons-codec.version>
<commons-math3.version>3.6.1</commons-math3.version>
</properties>
</project>

View File

@ -0,0 +1,33 @@
package com.baeldung.algorithms.balancedbinarytree;
public class BalancedBinaryTree {
public static boolean isBalanced(Tree tree) {
return isBalancedRecursive(tree, -1).isBalanced;
}
private static Result isBalancedRecursive(Tree tree, int depth) {
if (tree == null) {
return new Result(true, -1);
}
Result leftSubtreeResult = isBalancedRecursive(tree.left(), depth + 1);
Result rightSubtreeResult = isBalancedRecursive(tree.right(), depth + 1);
boolean isBalanced = Math.abs(leftSubtreeResult.height - rightSubtreeResult.height) <= 1;
boolean subtreesAreBalanced = leftSubtreeResult.isBalanced && rightSubtreeResult.isBalanced;
int height = Math.max(leftSubtreeResult.height, rightSubtreeResult.height) + 1;
return new Result(isBalanced && subtreesAreBalanced, height);
}
private static final class Result {
private final boolean isBalanced;
private final int height;
private Result(boolean isBalanced, int height) {
this.isBalanced = isBalanced;
this.height = height;
}
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.algorithms.balancedbinarytree;
public class Tree {
private final int value;
private final Tree left;
private final Tree right;
public Tree(int value, Tree left, Tree right) {
this.value = value;
this.left = left;
this.right = right;
}
public int value() {
return value;
}
public Tree left() {
return left;
}
public Tree right() {
return right;
}
@Override
public String toString() {
return String.format("[%s, %s, %s]",
value,
left == null ? "null" : left.toString(),
right == null ? "null" : right.toString()
);
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.algorithms.binarygap;
public class BinaryGap {
static int calculateBinaryGap(int n) {
return calculateBinaryGap(n >>> Integer.numberOfTrailingZeros(n), 0, 0);
}
static int calculateBinaryGap(int n, int current, int maximum) {
if (n == 0) {
return maximum;
} else if ((n & 1) == 0) {
return calculateBinaryGap(n >>> 1, current + 1, maximum);
} else {
return calculateBinaryGap(n >>> 1, 0, Math.max(maximum, current));
}
}
}

View File

@ -0,0 +1,83 @@
package com.baeldung.algorithms.caesarcipher;
import org.apache.commons.math3.stat.inference.ChiSquareTest;
import java.util.Arrays;
import java.util.stream.IntStream;
public class CaesarCipher {
private static final char LETTER_A = 'a';
private static final char LETTER_Z = 'z';
private static final int ALPHABET_SIZE = LETTER_Z - LETTER_A + 1;
private static final double[] ENGLISH_LETTERS_PROBABILITIES = {0.073, 0.009, 0.030, 0.044, 0.130, 0.028, 0.016, 0.035, 0.074, 0.002, 0.003, 0.035, 0.025, 0.078, 0.074, 0.027, 0.003, 0.077, 0.063, 0.093, 0.027, 0.013, 0.016, 0.005, 0.019, 0.001};
public String cipher(String message, int offset) {
StringBuilder result = new StringBuilder();
for (char character : message.toCharArray()) {
if (character != ' ') {
int originalAlphabetPosition = character - LETTER_A;
int newAlphabetPosition = (originalAlphabetPosition + offset) % ALPHABET_SIZE;
char newCharacter = (char) (LETTER_A + newAlphabetPosition);
result.append(newCharacter);
} else {
result.append(character);
}
}
return result.toString();
}
public String decipher(String message, int offset) {
return cipher(message, ALPHABET_SIZE - (offset % ALPHABET_SIZE));
}
public int breakCipher(String message) {
return probableOffset(chiSquares(message));
}
private double[] chiSquares(String message) {
double[] expectedLettersFrequencies = expectedLettersFrequencies(message.length());
double[] chiSquares = new double[ALPHABET_SIZE];
for (int offset = 0; offset < chiSquares.length; offset++) {
String decipheredMessage = decipher(message, offset);
long[] lettersFrequencies = observedLettersFrequencies(decipheredMessage);
double chiSquare = new ChiSquareTest().chiSquare(expectedLettersFrequencies, lettersFrequencies);
chiSquares[offset] = chiSquare;
}
return chiSquares;
}
private long[] observedLettersFrequencies(String message) {
return IntStream.rangeClosed(LETTER_A, LETTER_Z)
.mapToLong(letter -> countLetter((char) letter, message))
.toArray();
}
private long countLetter(char letter, String message) {
return message.chars()
.filter(character -> character == letter)
.count();
}
private double[] expectedLettersFrequencies(int messageLength) {
return Arrays.stream(ENGLISH_LETTERS_PROBABILITIES)
.map(probability -> probability * messageLength)
.toArray();
}
private int probableOffset(double[] chiSquares) {
int probableOffset = 0;
for (int offset = 0; offset < chiSquares.length; offset++) {
System.out.println(String.format("Chi-Square for offset %d: %.2f", offset, chiSquares[offset]));
if (chiSquares[offset] < chiSquares[probableOffset]) {
probableOffset = offset;
}
}
return probableOffset;
}
}

View File

@ -0,0 +1,67 @@
package com.baeldung.algorithms.combinatorics;
import java.util.*;
import static java.util.Collections.swap;
public class Combinatorics {
public static List<List<Integer>> permutations(List<Integer> sequence) {
List<List<Integer>> results = new ArrayList<>();
permutationsInternal(sequence, results, 0);
return results;
}
private static void permutationsInternal(List<Integer> sequence, List<List<Integer>> results, int index) {
if (index == sequence.size() - 1) {
results.add(new ArrayList<>(sequence));
}
for (int i = index; i < sequence.size(); i++) {
swap(sequence, i, index);
permutationsInternal(sequence, results, index + 1);
swap(sequence, i, index);
}
}
public static List<List<Integer>> combinations(List<Integer> inputSet, int k) {
List<List<Integer>> results = new ArrayList<>();
combinationsInternal(inputSet, k, results, new ArrayList<>(), 0);
return results;
}
private static void combinationsInternal(
List<Integer> inputSet, int k, List<List<Integer>> results, ArrayList<Integer> accumulator, int index) {
int leftToAccumulate = k - accumulator.size();
int possibleToAcculumate = inputSet.size() - index;
if (accumulator.size() == k) {
results.add(new ArrayList<>(accumulator));
} else if (leftToAccumulate <= possibleToAcculumate) {
combinationsInternal(inputSet, k, results, accumulator, index + 1);
accumulator.add(inputSet.get(index));
combinationsInternal(inputSet, k, results, accumulator, index + 1);
accumulator.remove(accumulator.size() - 1);
}
}
public static List<List<Character>> powerSet(List<Character> sequence) {
List<List<Character>> results = new ArrayList<>();
powerSetInternal(sequence, results, new ArrayList<>(), 0);
return results;
}
private static void powerSetInternal(
List<Character> set, List<List<Character>> powerSet, List<Character> accumulator, int index) {
if (index == set.size()) {
powerSet.add(new ArrayList<>(accumulator));
} else {
accumulator.add(set.get(index));
powerSetInternal(set, powerSet, accumulator, index + 1);
accumulator.remove(accumulator.size() - 1);
powerSetInternal(set, powerSet, accumulator, index + 1);
}
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.algorithms.knapsack;
public class Knapsack {
public int knapsackRec(int[] w, int[] v, int n, int W) {
if (n <= 0) {
return 0;
} else if (w[n - 1] > W) {
return knapsackRec(w, v, n - 1, W);
} else {
return Math.max(knapsackRec(w, v, n - 1, W), v[n - 1] + knapsackRec(w, v, n - 1, W - w[n - 1]));
}
}
public int knapsackDP(int[] w, int[] v, int n, int W) {
if (n <= 0 || W <= 0) {
return 0;
}
int[][] m = new int[n + 1][W + 1];
for (int j = 0; j <= W; j++) {
m[0][j] = 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= W; j++) {
if (w[i - 1] > j) {
m[i][j] = m[i - 1][j];
} else {
m[i][j] = Math.max(m[i - 1][j], m[i - 1][j - w[i - 1]] + v[i - 1]);
}
}
}
return m[n][W];
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.algorithms.balancedbinarytree;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
public class BalancedBinaryTreeUnitTest extends BinaryTreeDataProvider {
@Test
public void givenBalancedTrees_whenCallingIsBalanced_ShouldReturnTrue() {
for (Tree tree : balancedTrees()) {
assertTrue(toString(tree) + " should be balanced", BalancedBinaryTree.isBalanced(tree));
}
}
@Test
public void givenUnbalancedTrees_whenCallingIsBalanced_ShouldReturnFalse() {
for (Tree tree : unbalancedTrees()) {
assertFalse(toString(tree) + " should not be balanced", BalancedBinaryTree.isBalanced(tree));
}
}
private String toString(Tree tree) {
return tree != null ? tree.toString() : "null";
}
}

View File

@ -0,0 +1,69 @@
package com.baeldung.algorithms.balancedbinarytree;
import java.util.Arrays;
import java.util.Collection;
class BinaryTreeDataProvider {
static Collection<Tree> balancedTrees() {
return Arrays.asList(
null,
leaf(1),
tree(1, leaf(2), leaf(3)),
tree(
1,
leaf(2),
tree(3, leaf(4), null)
),
tree(
1,
tree(
2,
tree(3, leaf(4), null),
leaf(5)
),
tree(
6,
leaf(7),
tree(8, null, leaf(9))
)
)
);
}
static Collection<Tree> unbalancedTrees() {
return Arrays.asList(
tree(
1,
tree(2, leaf(3), null),
null
),
tree(
1,
tree(
2,
tree(3, leaf(4), leaf(5)),
null
),
tree(6, leaf(7), null)
),
tree(
1,
tree(2, leaf(3), null),
tree(
4,
tree(5, leaf(6), leaf(7)),
null
)
)
);
}
private static Tree leaf(int value) {
return new Tree(value, null, null);
}
private static Tree tree(int value, Tree left, Tree right) {
return new Tree(value, left, right);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.algorithms.binarygap;
import static com.baeldung.algorithms.binarygap.BinaryGap.calculateBinaryGap;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class BinaryGapUnitTest {
@Test public void givenNoOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() {
int result = calculateBinaryGap(63);
assertEquals(0, result);
}
@Test public void givenTrailingZeros_whenCalculateBinaryGap_thenOutputCorrectResult() {
int result = calculateBinaryGap(40);
assertEquals(1, result);
}
@Test public void givenSingleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() {
int result = calculateBinaryGap(9);
assertEquals(2, result);
}
@Test public void givenMultipleOccurrenceOfBoundedZeros_whenCalculateBinaryGap_thenOutputCorrectResult() {
int result = calculateBinaryGap(145);
assertEquals(3, result);
}
}

View File

@ -0,0 +1,83 @@
package com.baeldung.algorithms.caesarcipher;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class CaesarCipherUnitTest {
private static final String SENTENCE = "he told me i could never teach a llama to drive";
private static final String SENTENCE_SHIFTED_THREE = "kh wrog ph l frxog qhyhu whdfk d oodpd wr gulyh";
private static final String SENTENCE_SHIFTED_TEN = "ro dyvn wo s myevn xofob dokmr k vvkwk dy nbsfo";
private CaesarCipher algorithm = new CaesarCipher();
@Test
void givenSentenceAndShiftThree_whenCipher_thenCipheredMessageWithoutOverflow() {
String cipheredSentence = algorithm.cipher(SENTENCE, 3);
assertThat(cipheredSentence)
.isEqualTo(SENTENCE_SHIFTED_THREE);
}
@Test
void givenSentenceAndShiftTen_whenCipher_thenCipheredMessageWithOverflow() {
String cipheredSentence = algorithm.cipher(SENTENCE, 10);
assertThat(cipheredSentence)
.isEqualTo(SENTENCE_SHIFTED_TEN);
}
@Test
void givenSentenceAndShiftThirtySix_whenCipher_thenCipheredLikeTenMessageWithOverflow() {
String cipheredSentence = algorithm.cipher(SENTENCE, 36);
assertThat(cipheredSentence)
.isEqualTo(SENTENCE_SHIFTED_TEN);
}
@Test
void givenSentenceShiftedThreeAndShiftThree_whenDecipher_thenOriginalSentenceWithoutOverflow() {
String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_THREE, 3);
assertThat(decipheredSentence)
.isEqualTo(SENTENCE);
}
@Test
void givenSentenceShiftedTenAndShiftTen_whenDecipher_thenOriginalSentenceWithOverflow() {
String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_TEN, 10);
assertThat(decipheredSentence)
.isEqualTo(SENTENCE);
}
@Test
void givenSentenceShiftedTenAndShiftThirtySix_whenDecipher_thenOriginalSentenceWithOverflow() {
String decipheredSentence = algorithm.decipher(SENTENCE_SHIFTED_TEN, 36);
assertThat(decipheredSentence)
.isEqualTo(SENTENCE);
}
@Test
void givenSentenceShiftedThree_whenBreakCipher_thenOriginalSentence() {
int offset = algorithm.breakCipher(SENTENCE_SHIFTED_THREE);
assertThat(offset)
.isEqualTo(3);
assertThat(algorithm.decipher(SENTENCE_SHIFTED_THREE, offset))
.isEqualTo(SENTENCE);
}
@Test
void givenSentenceShiftedTen_whenBreakCipher_thenOriginalSentence() {
int offset = algorithm.breakCipher(SENTENCE_SHIFTED_TEN);
assertThat(offset)
.isEqualTo(10);
assertThat(algorithm.decipher(SENTENCE_SHIFTED_TEN, offset))
.isEqualTo(SENTENCE);
}
}

View File

@ -0,0 +1,80 @@
package com.baeldung.algorithms.combinatorics;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
public class CombinatoricsUnitTest {
@Test
public void givenEmptySequence_whenCallingPermutations_ShouldReturnEmptyList() {
List<Integer> sequence = Arrays.asList();
List<List<Integer>> permutations = Combinatorics.permutations(sequence);
assertEquals(0, permutations.size());
}
@Test
public void givenOneElementSequence_whenCallingPermutations_ShouldReturnPermutations() {
List<Integer> sequence = Arrays.asList(1);
List<List<Integer>> permutations = Combinatorics.permutations(sequence);
assertEquals(1, permutations.size());
assertEquals(1, permutations.get(0).size());
assertSame(1, permutations.get(0).get(0));
}
@Test
public void givenFourElementsSequence_whenCallingPermutations_ShouldReturnPermutations() {
List<Integer> sequence = Arrays.asList(1, 2, 3, 4);
List<List<Integer>> permutations = Combinatorics.permutations(sequence);
assertEquals(24, permutations.size());
assertEquals(24, new HashSet<>(permutations).size());
}
@Test
public void givenTwoElements_whenCalling3Combinations_ShouldReturnEmptyList() {
List<Integer> set = Arrays.asList(1, 2);
List<List<Integer>> combinations = Combinatorics.combinations(set, 3);
assertEquals(0, combinations.size());
}
@Test
public void givenThreeElements_whenCalling3Combinations_ShouldReturnOneCombination() {
List<Integer> set = Arrays.asList(1, 2, 3);
List<List<Integer>> combinations = Combinatorics.combinations(set, 3);
assertEquals(1, combinations.size());
assertEquals(combinations.get(0), Arrays.asList(1, 2, 3));
}
@Test
public void givenFourElements_whenCalling2Combinations_ShouldReturnCombinations() {
List<Integer> set = Arrays.asList(1, 2, 3, 4);
List<List<Integer>> combinations = Combinatorics.combinations(set, 2);
assertEquals(6, combinations.size());
assertEquals(6, new HashSet<>(combinations).size());
}
@Test
public void givenFourElements_whenCallingPowerSet_ShouldReturn15Sets() {
List<Character> sequence = Arrays.asList('a', 'b', 'c', 'd');
List<List<Character>> combinations = Combinatorics.powerSet(sequence);
assertEquals(16, combinations.size());
}
}

View File

@ -0,0 +1,44 @@
package com.baeldung.algorithms.knapsack;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class KnapsackUnitTest {
@Test
public void givenWeightsandValues_whenCalculateMax_thenOutputCorrectResult() {
final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 };
final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 };
final int n = 10;
final int W = 67;
final Knapsack knapsack = new Knapsack();
assertEquals(1270, knapsack.knapsackRec(w, v, n, W));
assertEquals(1270, knapsack.knapsackDP(w, v, n, W));
}
@Test
public void givenZeroItems_whenCalculateMax_thenOutputZero() {
final int[] w = new int[] {};
final int[] v = new int[] {};
final int n = 0;
final int W = 67;
final Knapsack knapsack = new Knapsack();
assertEquals(0, knapsack.knapsackRec(w, v, n, W));
assertEquals(0, knapsack.knapsackDP(w, v, n, W));
}
@Test
public void givenZeroWeightLimit_whenCalculateMax_thenOutputZero() {
final int[] w = new int[] { 23, 26, 20, 18, 32, 27, 29, 26, 30, 27 };
final int[] v = new int[] { 505, 352, 458, 220, 354, 414, 498, 545, 473, 543 };
final int n = 10;
final int W = 0;
final Knapsack knapsack = new Knapsack();
assertEquals(0, knapsack.knapsackRec(w, v, n, W));
assertEquals(0, knapsack.knapsackDP(w, v, n, W));
}
}

View File

@ -0,0 +1,11 @@
## Algorithms - Searching
This module contains articles about searching algorithms.
### Relevant articles:
- [Binary Search Algorithm in Java](https://www.baeldung.com/java-binary-search)
- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search)
- [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-search)
- [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search)
- [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms)
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search)

View File

@ -0,0 +1,38 @@
<?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>algorithms-searching</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>algorithms-searching</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${org.assertj.core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>algorithms-searching</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<org.assertj.core.version>3.9.0</org.assertj.core.version>
</properties>
</project>

View File

@ -1,55 +1,55 @@
package com.baeldung.algorithms.binarysearch;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class BinarySearch {
public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
int index = Integer.MAX_VALUE;
while (low <= high) {
int mid = (low + high) / 2;
if (sortedArray[mid] < key) {
low = mid + 1;
} else if (sortedArray[mid] > key) {
high = mid - 1;
} else if (sortedArray[mid] == key) {
index = mid;
break;
}
}
return index;
}
public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
int middle = (low + high) / 2;
if (high < low) {
return -1;
}
if (key == sortedArray[middle]) {
return middle;
} else if (key < sortedArray[middle]) {
return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
} else {
return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
}
}
public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
int index = Arrays.binarySearch(sortedArray, key);
return index;
}
public int runBinarySearchUsingJavaCollections(List<Integer> sortedList, Integer key) {
int index = Collections.binarySearch(sortedList, key);
return index;
}
}
package com.baeldung.algorithms.binarysearch;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class BinarySearch {
public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
int index = Integer.MAX_VALUE;
while (low <= high) {
int mid = (low + high) / 2;
if (sortedArray[mid] < key) {
low = mid + 1;
} else if (sortedArray[mid] > key) {
high = mid - 1;
} else if (sortedArray[mid] == key) {
index = mid;
break;
}
}
return index;
}
public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
int middle = (low + high) / 2;
if (high < low) {
return -1;
}
if (key == sortedArray[middle]) {
return middle;
} else if (key < sortedArray[middle]) {
return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
} else {
return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
}
}
public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
int index = Arrays.binarySearch(sortedArray, key);
return index;
}
public int runBinarySearchUsingJavaCollections(List<Integer> sortedList, Integer key) {
int index = Collections.binarySearch(sortedList, key);
return index;
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.algorithms.breadthfirstsearch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class BreadthFirstSearchAlgorithm {
private static final Logger LOGGER = LoggerFactory.getLogger(BreadthFirstSearchAlgorithm.class);
public static <T> Optional<Tree<T>> search(T value, Tree<T> root) {
Queue<Tree<T>> queue = new ArrayDeque<>();
queue.add(root);
Tree<T> currentNode;
while (!queue.isEmpty()) {
currentNode = queue.remove();
LOGGER.info("Visited node with value: {}", currentNode.getValue());
if (currentNode.getValue().equals(value)) {
return Optional.of(currentNode);
} else {
queue.addAll(currentNode.getChildren());
}
}
return Optional.empty();
}
public static <T> Optional<Node<T>> search(T value, Node<T> start) {
Queue<Node<T>> queue = new ArrayDeque<>();
queue.add(start);
Node<T> currentNode;
Set<Node<T>> alreadyVisited = new HashSet<>();
while (!queue.isEmpty()) {
currentNode = queue.remove();
LOGGER.info("Visited node with value: {}", currentNode.getValue());
if (currentNode.getValue().equals(value)) {
return Optional.of(currentNode);
} else {
alreadyVisited.add(currentNode);
queue.addAll(currentNode.getNeighbors());
queue.removeAll(alreadyVisited);
}
}
return Optional.empty();
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.algorithms.breadthfirstsearch;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class Node<T> {
private T value;
private Set<Node<T>> neighbors;
public Node(T value) {
this.value = value;
this.neighbors = new HashSet<>();
}
public T getValue() {
return value;
}
public Set<Node<T>> getNeighbors() {
return Collections.unmodifiableSet(neighbors);
}
public void connect(Node<T> node) {
if (this == node) throw new IllegalArgumentException("Can't connect node to itself");
this.neighbors.add(node);
node.neighbors.add(this);
}
}

View File

@ -0,0 +1,34 @@
package com.baeldung.algorithms.breadthfirstsearch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Tree<T> {
private T value;
private List<Tree<T>> children;
private Tree(T value) {
this.value = value;
this.children = new ArrayList<>();
}
public static <T> Tree<T> of(T value) {
return new Tree<>(value);
}
public T getValue() {
return value;
}
public List<Tree<T>> getChildren() {
return Collections.unmodifiableList(children);
}
public Tree<T> addChild(T value) {
Tree<T> newChild = new Tree<>(value);
children.add(newChild);
return newChild;
}
}

View File

@ -0,0 +1,227 @@
package com.baeldung.algorithms.dfs;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BinaryTree {
Node root;
public void add(int value) {
root = addRecursive(root, value);
}
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
}
return current;
}
public boolean isEmpty() {
return root == null;
}
public int getSize() {
return getSizeRecursive(root);
}
private int getSizeRecursive(Node current) {
return current == null ? 0 : getSizeRecursive(current.left) + 1 + getSizeRecursive(current.right);
}
public boolean containsNode(int value) {
return containsNodeRecursive(root, value);
}
private boolean containsNodeRecursive(Node current, int value) {
if (current == null) {
return false;
}
if (value == current.value) {
return true;
}
return value < current.value
? containsNodeRecursive(current.left, value)
: containsNodeRecursive(current.right, value);
}
public void delete(int value) {
root = deleteRecursive(root, value);
}
private Node deleteRecursive(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.value) {
// Case 1: no children
if (current.left == null && current.right == null) {
return null;
}
// Case 2: only 1 child
if (current.right == null) {
return current.left;
}
if (current.left == null) {
return current.right;
}
// Case 3: 2 children
int smallestValue = findSmallestValue(current.right);
current.value = smallestValue;
current.right = deleteRecursive(current.right, smallestValue);
return current;
}
if (value < current.value) {
current.left = deleteRecursive(current.left, value);
return current;
}
current.right = deleteRecursive(current.right, value);
return current;
}
private int findSmallestValue(Node root) {
return root.left == null ? root.value : findSmallestValue(root.left);
}
public void traverseInOrder(Node node) {
if (node != null) {
traverseInOrder(node.left);
visit(node.value);
traverseInOrder(node.right);
}
}
public void traversePreOrder(Node node) {
if (node != null) {
visit(node.value);
traversePreOrder(node.left);
traversePreOrder(node.right);
}
}
public void traversePostOrder(Node node) {
if (node != null) {
traversePostOrder(node.left);
traversePostOrder(node.right);
visit(node.value);
}
}
public void traverseLevelOrder() {
if (root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(" " + node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.left != null) {
nodes.add(node.right);
}
}
}
public void traverseInOrderWithoutRecursion() {
Stack<Node> stack = new Stack<Node>();
Node current = root;
stack.push(root);
while(! stack.isEmpty()) {
while(current.left != null) {
current = current.left;
stack.push(current);
}
current = stack.pop();
visit(current.value);
if(current.right != null) {
current = current.right;
stack.push(current);
}
}
}
public void traversePreOrderWithoutRecursion() {
Stack<Node> stack = new Stack<Node>();
Node current = root;
stack.push(root);
while(! stack.isEmpty()) {
current = stack.pop();
visit(current.value);
if(current.right != null)
stack.push(current.right);
if(current.left != null)
stack.push(current.left);
}
}
public void traversePostOrderWithoutRecursion() {
Stack<Node> stack = new Stack<Node>();
Node prev = root;
Node current = root;
stack.push(root);
while (!stack.isEmpty()) {
current = stack.peek();
boolean hasChild = (current.left != null || current.right != null);
boolean isPrevLastChild = (prev == current.right || (prev == current.left && current.right == null));
if (!hasChild || isPrevLastChild) {
current = stack.pop();
visit(current.value);
prev = current;
} else {
if (current.right != null) {
stack.push(current.right);
}
if (current.left != null) {
stack.push(current.left);
}
}
}
}
private void visit(int value) {
System.out.print(" " + value);
}
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
right = null;
left = null;
}
}
}

View File

@ -0,0 +1,74 @@
package com.baeldung.algorithms.dfs;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class Graph {
private Map<Integer, List<Integer>> adjVertices;
public Graph() {
this.adjVertices = new HashMap<Integer, List<Integer>>();
}
public void addVertex(int vertex) {
adjVertices.putIfAbsent(vertex, new ArrayList<>());
}
public void addEdge(int src, int dest) {
adjVertices.get(src).add(dest);
}
public void dfsWithoutRecursion(int start) {
Stack<Integer> stack = new Stack<Integer>();
boolean[] isVisited = new boolean[adjVertices.size()];
stack.push(start);
while (!stack.isEmpty()) {
int current = stack.pop();
isVisited[current] = true;
visit(current);
for (int dest : adjVertices.get(current)) {
if (!isVisited[dest])
stack.push(dest);
}
}
}
public void dfs(int start) {
boolean[] isVisited = new boolean[adjVertices.size()];
dfsRecursive(start, isVisited);
}
private void dfsRecursive(int current, boolean[] isVisited) {
isVisited[current] = true;
visit(current);
for (int dest : adjVertices.get(current)) {
if (!isVisited[dest])
dfsRecursive(dest, isVisited);
}
}
public List<Integer> topologicalSort(int start) {
LinkedList<Integer> result = new LinkedList<Integer>();
boolean[] isVisited = new boolean[adjVertices.size()];
topologicalSortRecursive(start, isVisited, result);
return result;
}
private void topologicalSortRecursive(int current, boolean[] isVisited, LinkedList<Integer> result) {
isVisited[current] = true;
for (int dest : adjVertices.get(current)) {
if (!isVisited[dest])
topologicalSortRecursive(dest, isVisited, result);
}
result.addFirst(current);
}
private void visit(int value) {
System.out.print(" " + value);
}
}

View File

@ -0,0 +1,194 @@
package com.baeldung.algorithms.textsearch;
import java.math.BigInteger;
import java.util.Random;
public class TextSearchAlgorithms {
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;
}
}

View File

@ -1,43 +1,41 @@
package com.baeldung.algorithms.binarysearch;
import java.util.Arrays;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import com.baeldung.algorithms.binarysearch.BinarySearch;
public class BinarySearchUnitTest {
int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
int key = 6;
int expectedIndexForSearchKey = 7;
int low = 0;
int high = sortedArray.length - 1;
List<Integer> sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
}
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
}
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
}
@Test
public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
}
}
package com.baeldung.algorithms.binarysearch;
import java.util.Arrays;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
public class BinarySearchUnitTest {
int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
int key = 6;
int expectedIndexForSearchKey = 7;
int low = 0;
int high = sortedArray.length - 1;
List<Integer> sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
}
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
}
@Test
public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
}
@Test
public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
BinarySearch binSearch = new BinarySearch();
Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
}
}

View File

@ -0,0 +1,86 @@
package com.baeldung.algorithms.breadthfirstsearch;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class BreadthFirstSearchAlgorithmUnitTest {
private Tree<Integer> root;
private Tree<Integer> rootFirstChild;
private Tree<Integer> depthMostChild;
private Tree<Integer> rootSecondChild;
private Node<Integer> start;
private Node<Integer> firstNeighbor;
private Node<Integer> firstNeighborNeighbor;
private Node<Integer> secondNeighbor;
@Test
void givenTree_whenSearchTen_thenRoot() {
initTree();
assertThat(BreadthFirstSearchAlgorithm.search(10, root)).isPresent().contains(root);
}
@Test
void givenTree_whenSearchThree_thenDepthMostValue() {
initTree();
assertThat(BreadthFirstSearchAlgorithm.search(3, root)).isPresent().contains(depthMostChild);
}
@Test
void givenTree_whenSearchFour_thenRootSecondChild() {
initTree();
assertThat(BreadthFirstSearchAlgorithm.search(4, root)).isPresent().contains(rootSecondChild);
}
@Test
void givenTree_whenSearchFive_thenNotFound() {
initTree();
assertThat(BreadthFirstSearchAlgorithm.search(5, root)).isEmpty();
}
private void initTree() {
root = Tree.of(10);
rootFirstChild = root.addChild(2);
depthMostChild = rootFirstChild.addChild(3);
rootSecondChild = root.addChild(4);
}
@Test
void givenNode_whenSearchTen_thenStart() {
initNode();
assertThat(BreadthFirstSearchAlgorithm.search(10, firstNeighborNeighbor)).isPresent().contains(start);
}
@Test
void givenNode_whenSearchThree_thenNeighborNeighbor() {
initNode();
assertThat(BreadthFirstSearchAlgorithm.search(3, firstNeighborNeighbor)).isPresent().contains(firstNeighborNeighbor);
}
@Test
void givenNode_whenSearchFour_thenSecondNeighbor() {
initNode();
assertThat(BreadthFirstSearchAlgorithm.search(4, firstNeighborNeighbor)).isPresent().contains(secondNeighbor);
}
@Test
void givenNode_whenSearchFive_thenNotFound() {
initNode();
assertThat(BreadthFirstSearchAlgorithm.search(5, firstNeighborNeighbor)).isEmpty();
}
private void initNode() {
start = new Node<>(10);
firstNeighbor = new Node<>(2);
start.connect(firstNeighbor);
firstNeighborNeighbor = new Node<>(3);
firstNeighbor.connect(firstNeighborNeighbor);
firstNeighborNeighbor.connect(start);
secondNeighbor = new Node<>(4);
start.connect(secondNeighbor);
}
}

View File

@ -0,0 +1,136 @@
package com.baeldung.algorithms.dfs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class BinaryTreeUnitTest {
@Test
public void givenABinaryTree_WhenAddingElements_ThenTreeNotEmpty() {
BinaryTree bt = createBinaryTree();
assertTrue(!bt.isEmpty());
}
@Test
public void givenABinaryTree_WhenAddingElements_ThenTreeContainsThoseElements() {
BinaryTree bt = createBinaryTree();
assertTrue(bt.containsNode(6));
assertTrue(bt.containsNode(4));
assertFalse(bt.containsNode(1));
}
@Test
public void givenABinaryTree_WhenAddingExistingElement_ThenElementIsNotAdded() {
BinaryTree bt = createBinaryTree();
int initialSize = bt.getSize();
assertTrue(bt.containsNode(3));
bt.add(3);
assertEquals(initialSize, bt.getSize());
}
@Test
public void givenABinaryTree_WhenLookingForNonExistingElement_ThenReturnsFalse() {
BinaryTree bt = createBinaryTree();
assertFalse(bt.containsNode(99));
}
@Test
public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() {
BinaryTree bt = createBinaryTree();
assertTrue(bt.containsNode(9));
bt.delete(9);
assertFalse(bt.containsNode(9));
}
@Test
public void givenABinaryTree_WhenDeletingNonExistingElement_ThenTreeDoesNotDelete() {
BinaryTree bt = createBinaryTree();
int initialSize = bt.getSize();
assertFalse(bt.containsNode(99));
bt.delete(99);
assertFalse(bt.containsNode(99));
assertEquals(initialSize, bt.getSize());
}
@Test
public void it_deletes_the_root() {
int value = 12;
BinaryTree bt = new BinaryTree();
bt.add(value);
assertTrue(bt.containsNode(value));
bt.delete(value);
assertFalse(bt.containsNode(value));
}
@Test
public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
BinaryTree bt = createBinaryTree();
bt.traverseInOrder(bt.root);
System.out.println();
bt.traverseInOrderWithoutRecursion();
}
@Test
public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() {
BinaryTree bt = createBinaryTree();
bt.traversePreOrder(bt.root);
System.out.println();
bt.traversePreOrderWithoutRecursion();
}
@Test
public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() {
BinaryTree bt = createBinaryTree();
bt.traversePostOrder(bt.root);
System.out.println();
bt.traversePostOrderWithoutRecursion();
}
@Test
public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() {
BinaryTree bt = createBinaryTree();
bt.traverseLevelOrder();
}
private BinaryTree createBinaryTree() {
BinaryTree bt = new BinaryTree();
bt.add(6);
bt.add(4);
bt.add(8);
bt.add(3);
bt.add(5);
bt.add(7);
bt.add(9);
return bt;
}
}

View File

@ -1,7 +1,8 @@
package com.baeldung.graph;
package com.baeldung.algorithms.dfs;
import java.util.List;
import com.baeldung.algorithms.dfs.Graph;
import org.junit.Test;
public class GraphUnitTest {

View File

@ -1,10 +1,10 @@
package com.baeldung.algorithms.interpolationsearch;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Before;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class InterpolationSearchUnitTest {
private int[] myData;

View File

@ -0,0 +1,23 @@
package com.baeldung.algorithms.textsearch;
import org.junit.Assert;
import org.junit.Test;
public class TextSearchAlgorithmsUnitTest {
@Test
public void testStringSearchAlgorithms() {
String text = "This is some nice text.";
String pattern = "some";
int realPosition = text.indexOf(pattern);
Assert.assertTrue(realPosition == TextSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
Assert.assertTrue(realPosition == TextSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
Assert.assertTrue(realPosition == TextSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
Assert.assertTrue(realPosition == TextSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
Assert.assertTrue(realPosition == TextSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
}
}

View File

@ -1,8 +1,20 @@
## Relevant articles:
## Algorithms - Sorting
- [Bubble Sort in Java](http://www.baeldung.com/java-bubble-sort)
This module contains articles about sorting algorithms.
### Relevant articles:
- [Bubble Sort in Java](https://www.baeldung.com/java-bubble-sort)
- [Merge Sort in Java](https://www.baeldung.com/java-merge-sort)
- [Quicksort Algorithm Implementation in Java](https://www.baeldung.com/java-quicksort)
- [Insertion Sort in Java](https://www.baeldung.com/java-insertion-sort)
- [Heap Sort in Java](https://www.baeldung.com/java-heap-sort)
- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort)
- [Counting Sort in Java](https://www.baeldung.com/java-counting-sort)
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
- [Selection Sort in Java](https://www.baeldung.com/java-selection-sort)
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
- [Radix Sort in Java](https://www.baeldung.com/java-radix-sort)
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
- [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort)

Some files were not shown because too many files have changed in this diff Show More