Merge branch 'master' of https://github.com/eugenp/tutorials
Conflicts: spring-websockets/src/main/resources/public/index.html
This commit is contained in:
commit
7f1ed45993
12
.gitignore
vendored
12
.gitignore
vendored
@ -73,8 +73,6 @@ ninja/devDb.mv.db
|
|||||||
**/out-tsc
|
**/out-tsc
|
||||||
**/nbproject/
|
**/nbproject/
|
||||||
**/nb-configuration.xml
|
**/nb-configuration.xml
|
||||||
core-scala/.cache-main
|
|
||||||
core-scala/.cache-tests
|
|
||||||
|
|
||||||
|
|
||||||
persistence-modules/hibernate5/transaction.log
|
persistence-modules/hibernate5/transaction.log
|
||||||
@ -87,7 +85,9 @@ transaction.log
|
|||||||
*-shell.log
|
*-shell.log
|
||||||
|
|
||||||
apache-cxf/cxf-aegis/baeldung.xml
|
apache-cxf/cxf-aegis/baeldung.xml
|
||||||
apache-fop/src/test/resources/input.xml
|
testing-modules/report-*.json
|
||||||
apache-fop/src/test/resources/output_herold.pdf
|
|
||||||
apache-fop/src/test/resources/output_html2fo.pdf
|
libraries-2/*.db
|
||||||
apache-fop/src/test/resources/output_jtidy.pdf
|
|
||||||
|
# SDKMan
|
||||||
|
.sdkmanrc
|
||||||
|
46
README.md
46
README.md
@ -1,5 +1,3 @@
|
|||||||
**UPDATE**: The price of "Learn Spring Security OAuth" will permanently change on the 11th of December, along with the upcoming OAuth2 material: http://bit.ly/github-lss
|
|
||||||
|
|
||||||
The Courses
|
The Courses
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
@ -22,10 +20,38 @@ This project is **a collection of small and focused tutorials** - each covering
|
|||||||
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Security.
|
A strong focus of these is, of course, the Spring Framework - Spring, Spring Boot and Spring Security.
|
||||||
In additional to Spring, the modules here are covering a number of aspects in Java.
|
In additional to Spring, the modules here are covering a number of aspects in Java.
|
||||||
|
|
||||||
|
Profile based segregation
|
||||||
|
====================
|
||||||
|
|
||||||
|
We are using maven build profiles to segregate the huge list of individual projects we have in our repository.
|
||||||
|
|
||||||
|
The projects are broadly divided into 3 list: first, second and heavy.
|
||||||
|
|
||||||
|
Next, they are segregated further on the basis of tests that we want to execute.
|
||||||
|
|
||||||
|
Therefore, we have a total of 6 profiles:
|
||||||
|
|
||||||
|
| Profile | Includes | Type of test enabled |
|
||||||
|
| ----------------------- | --------------------------- | -------------------- |
|
||||||
|
| default-first | First set of projects | *UnitTest |
|
||||||
|
| integration-lite-first | First set of projects | *IntegrationTest |
|
||||||
|
| default-second | Second set of projects | *UnitTest |
|
||||||
|
| integration-lite-second | Second set of projects | *IntegrationTest |
|
||||||
|
| default-heavy | Heavy/long running projects | *UnitTest |
|
||||||
|
| integration-heavy | Heavy/long running projects | *IntegrationTest |
|
||||||
|
|
||||||
Building the project
|
Building the project
|
||||||
====================
|
====================
|
||||||
To do the full build, do: `mvn clean install`
|
|
||||||
|
Though it should not be needed often to build the entire repository at once because we are usually concerned with a specific module.
|
||||||
|
|
||||||
|
But if we want to, we can invoke the below command from the root of the repository if we want to build the entire repository with only Unit Tests enabled:
|
||||||
|
|
||||||
|
`mvn clean install -Pdefault-first,default-second,default-heavy`
|
||||||
|
|
||||||
|
or if we want to build the entire repository with Integration Tests enabled, we can do:
|
||||||
|
|
||||||
|
`mvn clean install -Pintegration-lite-first,integration-lite-second,integration-heavy`
|
||||||
|
|
||||||
|
|
||||||
Building a single module
|
Building a single module
|
||||||
@ -46,8 +72,18 @@ When you're working with an individual module, there's no need to import all of
|
|||||||
|
|
||||||
Running Tests
|
Running Tests
|
||||||
=============
|
=============
|
||||||
The command `mvn clean install` will run the unit tests in a module.
|
The command `mvn clean install` from within a module will run the unit tests in that module.
|
||||||
To run the integration tests, use the command `mvn clean install -Pintegration-lite-first`
|
For Spring modules this will also run the `SpringContextTest` if present.
|
||||||
|
|
||||||
|
To run the integration tests, use the command:
|
||||||
|
|
||||||
|
`mvn clean install -Pintegration-lite-first` or
|
||||||
|
|
||||||
|
`mvn clean install -Pintegration-lite-second` or
|
||||||
|
|
||||||
|
`mvn clean install -Pintegration-heavy`
|
||||||
|
|
||||||
|
depending on the list where our module exists
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>akka-http</artifactId>
|
<artifactId>akka-http</artifactId>
|
||||||
<name>akka-http</name>
|
<name>akka-http</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>akka-streams</artifactId>
|
<artifactId>akka-streams</artifactId>
|
||||||
<name>akka-streams</name>
|
<name>akka-streams</name>
|
||||||
|
@ -5,6 +5,6 @@ This module contains articles about genetic algorithms.
|
|||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Introduction to Jenetics Library](https://www.baeldung.com/jenetics)
|
- [Introduction to Jenetics Library](https://www.baeldung.com/jenetics)
|
||||||
- [Ant Colony Optimization](https://www.baeldung.com/java-ant-colony-optimization)
|
- [Ant Colony Optimization with a Java Example](https://www.baeldung.com/java-ant-colony-optimization)
|
||||||
- [Design a Genetic Algorithm in Java](https://www.baeldung.com/java-genetic-algorithm)
|
- [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)
|
- [The Traveling Salesman Problem in Java](https://www.baeldung.com/java-simulated-annealing-for-traveling-salesman)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-genetic</artifactId>
|
<artifactId>algorithms-genetic</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -6,8 +6,8 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Validating Input With Finite Automata in Java](https://www.baeldung.com/java-finite-automata)
|
- [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)
|
- [Example of Hill Climbing Algorithm in Java](https://www.baeldung.com/java-hill-climbing-algorithm)
|
||||||
- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
|
- [Introduction to Minimax Algorithm with a Java Implementation](https://www.baeldung.com/java-minimax-algorithm)
|
||||||
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
|
- [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)
|
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
|
||||||
- More articles: [[next -->]](/../algorithms-miscellaneous-2)
|
- More articles: [[next -->]](/algorithms-miscellaneous-2)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-miscellaneous-1</artifactId>
|
<artifactId>algorithms-miscellaneous-1</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -14,4 +14,4 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words)
|
- [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)
|
- [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations)
|
||||||
- [Implementing A* Pathfinding in Java](https://www.baeldung.com/java-a-star-pathfinding)
|
- [Implementing A* Pathfinding in Java](https://www.baeldung.com/java-a-star-pathfinding)
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-1) [[next -->]](/../algorithms-miscellaneous-3)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-1) [[next -->]](/algorithms-miscellaneous-3)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-miscellaneous-2</artifactId>
|
<artifactId>algorithms-miscellaneous-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
package com.baeldung.jgrapht;
|
package com.baeldung.jgrapht;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.jgrapht.ext.JGraphXAdapter;
|
import org.jgrapht.ext.JGraphXAdapter;
|
||||||
import org.jgrapht.graph.DefaultDirectedGraph;
|
import org.jgrapht.graph.DefaultDirectedGraph;
|
||||||
import org.jgrapht.graph.DefaultEdge;
|
import org.jgrapht.graph.DefaultEdge;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.mxgraph.layout.mxCircleLayout;
|
import com.mxgraph.layout.mxCircleLayout;
|
||||||
import com.mxgraph.layout.mxIGraphLayout;
|
import com.mxgraph.layout.mxIGraphLayout;
|
||||||
import com.mxgraph.util.mxCellRenderer;
|
import com.mxgraph.util.mxCellRenderer;
|
||||||
@ -20,7 +25,7 @@ public class GraphImageGenerationUnitTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createGraph() throws IOException {
|
public void createGraph() throws IOException {
|
||||||
File imgFile = new File("src/test/resources/graph.png");
|
File imgFile = new File("src/test/resources/graph1.png");
|
||||||
imgFile.createNewFile();
|
imgFile.createNewFile();
|
||||||
g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
|
g = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
|
||||||
String x1 = "x1";
|
String x1 = "x1";
|
||||||
@ -34,12 +39,18 @@ public class GraphImageGenerationUnitTest {
|
|||||||
g.addEdge(x3, x1);
|
g.addEdge(x3, x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() {
|
||||||
|
File imgFile = new File("src/test/resources/graph1.png");
|
||||||
|
imgFile.deleteOnExit();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenAdaptedGraph_whenWriteBufferedImage_ThenFileShouldExist() throws IOException {
|
public void givenAdaptedGraph_whenWriteBufferedImage_ThenFileShouldExist() throws IOException {
|
||||||
JGraphXAdapter<String, DefaultEdge> graphAdapter = new JGraphXAdapter<String, DefaultEdge>(g);
|
JGraphXAdapter<String, DefaultEdge> graphAdapter = new JGraphXAdapter<String, DefaultEdge>(g);
|
||||||
mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
|
mxIGraphLayout layout = new mxCircleLayout(graphAdapter);
|
||||||
layout.execute(graphAdapter.getDefaultParent());
|
layout.execute(graphAdapter.getDefaultParent());
|
||||||
File imgFile = new File("src/test/resources/graph.png");
|
File imgFile = new File("src/test/resources/graph1.png");
|
||||||
BufferedImage image = mxCellRenderer.createBufferedImage(graphAdapter, null, 2, Color.WHITE, true, null);
|
BufferedImage image = mxCellRenderer.createBufferedImage(graphAdapter, null, 2, Color.WHITE, true, null);
|
||||||
ImageIO.write(image, "PNG", imgFile);
|
ImageIO.write(image, "PNG", imgFile);
|
||||||
assertTrue(imgFile.exists());
|
assertTrue(imgFile.exists());
|
||||||
|
@ -13,6 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
|
- [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)
|
- [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)
|
- [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)
|
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
||||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-miscellaneous-3</artifactId>
|
<artifactId>algorithms-miscellaneous-3</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -5,8 +5,8 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm)
|
- [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)
|
- [Check If a String Contains All The Letters of The Alphabet with Java](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 the Middle Element of a Linked List in Java](https://www.baeldung.com/java-linked-list-middle-element)
|
||||||
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
|
- [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)
|
- [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)
|
- [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-miscellaneous-4</artifactId>
|
<artifactId>algorithms-miscellaneous-4</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -9,14 +9,11 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||||||
- [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree)
|
- [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)
|
- [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)
|
- [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)
|
- [How to Determine if a Binary Tree is Balanced in Java](https://www.baeldung.com/java-balanced-binary-tree)
|
||||||
- [Overview of Combinatorial Problems in Java](https://www.baeldung.com/java-combinatorial-algorithms)
|
- [Overview of Combinatorial Problems in Java](https://www.baeldung.com/java-combinatorial-algorithms)
|
||||||
- [Prim’s Algorithm](https://www.baeldung.com/java-prim-algorithm)
|
- [Prim’s Algorithm with a Java Implementation](https://www.baeldung.com/java-prim-algorithm)
|
||||||
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
- [Maximum Subarray Problem in Java](https://www.baeldung.com/java-maximum-subarray)
|
||||||
- [How to Merge Two Sorted Arrays](https://www.baeldung.com/java-merge-sorted-arrays)
|
- [How to Merge Two Sorted Arrays in Java](https://www.baeldung.com/java-merge-sorted-arrays)
|
||||||
- [Median of Stream of Integers using Heap](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
- [Median of Stream of Integers using Heap in Java](https://www.baeldung.com/java-stream-integers-median-using-heap)
|
||||||
- [Kruskal’s Algorithm for Spanning Trees](https://www.baeldung.com/java-spanning-trees-kruskal)
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-4) [[next -->]](/algorithms-miscellaneous-6)
|
||||||
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
|
||||||
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
|
||||||
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
|
||||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-miscellaneous-5</artifactId>
|
<artifactId>algorithms-miscellaneous-5</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
@ -23,12 +25,6 @@
|
|||||||
<artifactId>commons-math3</artifactId>
|
<artifactId>commons-math3</artifactId>
|
||||||
<version>${commons-math3.version}</version>
|
<version>${commons-math3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>${lombok.version}</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.allegro.finance</groupId>
|
<groupId>pl.allegro.finance</groupId>
|
||||||
<artifactId>tradukisto</artifactId>
|
<artifactId>tradukisto</artifactId>
|
||||||
@ -39,11 +35,6 @@
|
|||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>${guava.version}</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.platform</groupId>
|
<groupId>org.junit.platform</groupId>
|
||||||
<artifactId>junit-platform-commons</artifactId>
|
<artifactId>junit-platform-commons</artifactId>
|
||||||
@ -76,7 +67,6 @@
|
|||||||
<commons-codec.version>1.11</commons-codec.version>
|
<commons-codec.version>1.11</commons-codec.version>
|
||||||
<commons-math3.version>3.6.1</commons-math3.version>
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
<guava.version>28.1-jre</guava.version>
|
<guava.version>28.1-jre</guava.version>
|
||||||
<jackson.version>2.10.2</jackson.version>
|
|
||||||
<junit.platform.version>1.6.0</junit.platform.version>
|
<junit.platform.version>1.6.0</junit.platform.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
public class BoruvkaMST {
|
|
||||||
|
|
||||||
private static Tree mst = new Tree();
|
|
||||||
private static int totalWeight;
|
|
||||||
|
|
||||||
public BoruvkaMST(Graph graph) {
|
|
||||||
DisjointSet dSet = new DisjointSet(graph.getNodes());
|
|
||||||
|
|
||||||
// repeat at most log N times or until we have N-1 edges
|
|
||||||
for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
|
|
||||||
|
|
||||||
// foreach tree in forest, find closest edge
|
|
||||||
Edge[] closestEdgeArray = new Edge[graph.getNodes()];
|
|
||||||
for (Edge edge : graph.getAllEdges()) {
|
|
||||||
int first = edge.getFirst();
|
|
||||||
int second = edge.getSecond();
|
|
||||||
int firstParent = dSet.getParent(first);
|
|
||||||
int secondParent = dSet.getParent(second);
|
|
||||||
if (firstParent == secondParent) {
|
|
||||||
continue; // same tree
|
|
||||||
}
|
|
||||||
if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
|
|
||||||
closestEdgeArray[firstParent] = edge;
|
|
||||||
}
|
|
||||||
if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
|
|
||||||
closestEdgeArray[secondParent] = edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add newly discovered edges to MST
|
|
||||||
for (int i = 0; i < graph.getNodes(); i++) {
|
|
||||||
Edge edge = closestEdgeArray[i];
|
|
||||||
if (edge != null) {
|
|
||||||
int first = edge.getFirst();
|
|
||||||
int second = edge.getSecond();
|
|
||||||
// don't add the same edge twice
|
|
||||||
if (dSet.getParent(first) != dSet.getParent(second)) {
|
|
||||||
mst.addEdge(edge);
|
|
||||||
totalWeight += edge.getWeight();
|
|
||||||
dSet.union(first, second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterable<Edge> getMST() {
|
|
||||||
return mst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotalWeight() {
|
|
||||||
return totalWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class DisjointSet {
|
|
||||||
|
|
||||||
private int[] nodeParents;
|
|
||||||
private int[] nodeRanks;
|
|
||||||
|
|
||||||
public DisjointSet(int n) {
|
|
||||||
nodeParents = new int[n];
|
|
||||||
nodeRanks = new int[n];
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
nodeParents[i] = i;
|
|
||||||
nodeRanks[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getParent(int node) {
|
|
||||||
while (node != nodeParents[node]) {
|
|
||||||
node = nodeParents[node];
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void union(int node1, int node2) {
|
|
||||||
int node1Parent = getParent(node1);
|
|
||||||
int node2Parent = getParent(node2);
|
|
||||||
if (node1Parent == node2Parent) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
|
|
||||||
nodeParents[node1Parent] = node2Parent;
|
|
||||||
}
|
|
||||||
else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
|
|
||||||
nodeParents[node2Parent] = node1Parent;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nodeParents[node2Parent] = node1Parent;
|
|
||||||
nodeRanks[node1Parent]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
public class Edge {
|
|
||||||
|
|
||||||
private final int first;
|
|
||||||
private final int second;
|
|
||||||
private final int weight;
|
|
||||||
|
|
||||||
public Edge(int first, int second, int weight) {
|
|
||||||
this.first = first;
|
|
||||||
this.second = second;
|
|
||||||
this.weight = weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getFirst() {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSecond() {
|
|
||||||
return second;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOtherNode(int firstNode) {
|
|
||||||
int secondNode = 0;
|
|
||||||
if (firstNode == first)
|
|
||||||
secondNode = second;
|
|
||||||
else if (firstNode == second)
|
|
||||||
secondNode = first;
|
|
||||||
return secondNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return String.format("%d-%d %d", first, second, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
|
|
||||||
public class Graph {
|
|
||||||
|
|
||||||
private int nodes;
|
|
||||||
private int edges;
|
|
||||||
private Tree[] trees;
|
|
||||||
|
|
||||||
public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
|
|
||||||
nodes = jsonGraph.getNodes();
|
|
||||||
trees = (Tree[]) new Tree[nodes];
|
|
||||||
for (int i = 0; i < nodes; i++) {
|
|
||||||
trees[i] = new Tree();
|
|
||||||
}
|
|
||||||
|
|
||||||
int edgesFromInput = jsonGraph.getEdges();
|
|
||||||
for (int i = 0; i < edgesFromInput; i++) {
|
|
||||||
int first = jsonGraph.getEdgeList()
|
|
||||||
.get(i)
|
|
||||||
.getFirst();
|
|
||||||
int second = jsonGraph.getEdgeList()
|
|
||||||
.get(i)
|
|
||||||
.getSecond();
|
|
||||||
int weight = jsonGraph.getEdgeList()
|
|
||||||
.get(i)
|
|
||||||
.getWeight();
|
|
||||||
Edge edge = new Edge(first, second, weight);
|
|
||||||
|
|
||||||
trees[first].addEdge(edge);
|
|
||||||
trees[second].addEdge(edge);
|
|
||||||
edges++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNodes() {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEdges() {
|
|
||||||
return edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterable<Edge> iterableTree(int i) {
|
|
||||||
return trees[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterable<Edge> getAllEdges() {
|
|
||||||
Iterable<Edge> list = new Tree();
|
|
||||||
for (int i = 0; i < nodes; i++) {
|
|
||||||
for (Edge edge : iterableTree(i)) {
|
|
||||||
if (edge.getOtherNode(i) > i) {
|
|
||||||
((Tree) list).addEdge(edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Input {
|
|
||||||
private int nodes;
|
|
||||||
private int edges;
|
|
||||||
private List<E> edgeList;
|
|
||||||
|
|
||||||
public int getNodes() {
|
|
||||||
return nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNodes(int nodes) {
|
|
||||||
this.nodes = nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEdges() {
|
|
||||||
return edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEdges(int edges) {
|
|
||||||
this.edges = edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<E> getEdgeList() {
|
|
||||||
return edgeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEdgeList(List<E> edgeList) {
|
|
||||||
this.edgeList = edgeList;
|
|
||||||
}
|
|
||||||
|
|
||||||
static class E {
|
|
||||||
private int first;
|
|
||||||
private int second;
|
|
||||||
private int weight;
|
|
||||||
|
|
||||||
public int getFirst() {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFirst(int first) {
|
|
||||||
this.first = first;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSecond() {
|
|
||||||
return second;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecond(int second) {
|
|
||||||
this.second = second;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWeight() {
|
|
||||||
return weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWeight(int weight) {
|
|
||||||
this.weight = weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class Tree implements Iterable<Edge> {
|
|
||||||
private Node root;
|
|
||||||
private int edgeCount;
|
|
||||||
|
|
||||||
private static class Node {
|
|
||||||
private Edge edge;
|
|
||||||
private Node next;
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
String nextStr = next != null ? next.toString() : "";
|
|
||||||
return edge.toString() + " | " + nextStr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tree() {
|
|
||||||
root = null;
|
|
||||||
edgeCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEdgeCount() {
|
|
||||||
return edgeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addEdge(Edge edge) {
|
|
||||||
Node oldRoot = root;
|
|
||||||
root = new Node();
|
|
||||||
root.edge = edge;
|
|
||||||
root.next = oldRoot;
|
|
||||||
edgeCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
String rootStr = root != null ? root.toString() : "";
|
|
||||||
return "Tree: " + rootStr + "Size: " + edgeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<Edge> iterator() {
|
|
||||||
return new LinkedIterator(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class LinkedIterator implements Iterator<Edge> {
|
|
||||||
private Node current;
|
|
||||||
|
|
||||||
public LinkedIterator(Node root) {
|
|
||||||
current = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
|
||||||
return current != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Edge next() {
|
|
||||||
Edge edge = current.edge;
|
|
||||||
current = current.next;
|
|
||||||
return edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.baeldung.algorithms.boruvka;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParseException;
|
|
||||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
public class BoruvkaUnitTest {
|
|
||||||
|
|
||||||
private Input input;
|
|
||||||
private static String INPUT_JSON = "/input.json";
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
StringBuilder jsonStr = new StringBuilder();
|
|
||||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
jsonStr.append(line)
|
|
||||||
.append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input = mapper.readValue(jsonStr.toString(), Input.class);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
|
|
||||||
Graph graph = new Graph(input);
|
|
||||||
BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
|
|
||||||
|
|
||||||
Tree mst = (Tree) boruvkaMST.getMST();
|
|
||||||
|
|
||||||
assertEquals(30, boruvkaMST.getTotalWeight());
|
|
||||||
assertEquals(4, mst.getEdgeCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
13
algorithms-miscellaneous-6/README.md
Normal file
13
algorithms-miscellaneous-6/README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Boruvka’s Algorithm for Minimum Spanning Trees in Java](https://www.baeldung.com/java-boruvka-algorithm)
|
||||||
|
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
||||||
|
- [Kruskal’s Algorithm for Spanning Trees with a Java Implementation](https://www.baeldung.com/java-spanning-trees-kruskal)
|
||||||
|
- [Balanced Brackets Algorithm in Java](https://www.baeldung.com/java-balanced-brackets-algorithm)
|
||||||
|
- [Efficiently Merge Sorted Java Sequences](https://www.baeldung.com/java-merge-sorted-sequences)
|
||||||
|
- [Introduction to Greedy Algorithms with Java](https://www.baeldung.com/java-greedy-algorithms)
|
||||||
|
- [The Caesar Cipher in Java](https://www.baeldung.com/java-caesar-cipher)
|
||||||
|
- [Implementing a 2048 Solver in Java](https://www.baeldung.com/2048-java-solver)
|
||||||
|
- [Finding Top K Elements in a Java Array](https://www.baeldung.com/java-array-top-elements)
|
||||||
|
- [Reversing a Linked List in Java](https://www.baeldung.com/java-reverse-linked-list)
|
||||||
|
- More articles: [[<-- prev]](/algorithms-miscellaneous-5)
|
52
algorithms-miscellaneous-6/pom.xml
Normal file
52
algorithms-miscellaneous-6/pom.xml
Normal 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-6</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>algorithms-miscellaneous-6</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.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-commons</artifactId>
|
||||||
|
<version>${junit.platform.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>${org.assertj.core.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-math3</artifactId>
|
||||||
|
<version>${commons-math3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<guava.version>28.1-jre</guava.version>
|
||||||
|
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||||
|
<junit.platform.version>1.6.0</junit.platform.version>
|
||||||
|
<commons-math3.version>3.6.1</commons-math3.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import com.google.common.graph.EndpointPair;
|
||||||
|
import com.google.common.graph.MutableValueGraph;
|
||||||
|
import com.google.common.graph.ValueGraphBuilder;
|
||||||
|
|
||||||
|
public class BoruvkaMST {
|
||||||
|
|
||||||
|
private static MutableValueGraph<Integer, Integer> mst = ValueGraphBuilder.undirected()
|
||||||
|
.build();
|
||||||
|
private static int totalWeight;
|
||||||
|
|
||||||
|
public BoruvkaMST(MutableValueGraph<Integer, Integer> graph) {
|
||||||
|
|
||||||
|
int size = graph.nodes().size();
|
||||||
|
|
||||||
|
UnionFind uf = new UnionFind(size);
|
||||||
|
|
||||||
|
// repeat at most log N times or until we have N-1 edges
|
||||||
|
for (int t = 1; t < size && mst.edges().size() < size - 1; t = t + t) {
|
||||||
|
|
||||||
|
EndpointPair<Integer>[] closestEdgeArray = new EndpointPair[size];
|
||||||
|
|
||||||
|
// foreach tree in graph, find closest edge
|
||||||
|
for (EndpointPair<Integer> edge : graph.edges()) {
|
||||||
|
int u = edge.nodeU();
|
||||||
|
int v = edge.nodeV();
|
||||||
|
int uParent = uf.find(u);
|
||||||
|
int vParent = uf.find(v);
|
||||||
|
if (uParent == vParent) {
|
||||||
|
continue; // same tree
|
||||||
|
}
|
||||||
|
|
||||||
|
int weight = graph.edgeValueOrDefault(u, v, 0);
|
||||||
|
|
||||||
|
if (closestEdgeArray[uParent] == null) {
|
||||||
|
closestEdgeArray[uParent] = edge;
|
||||||
|
}
|
||||||
|
if (closestEdgeArray[vParent] == null) {
|
||||||
|
closestEdgeArray[vParent] = edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
int uParentWeight = graph.edgeValueOrDefault(closestEdgeArray[uParent].nodeU(), closestEdgeArray[uParent].nodeV(), 0);
|
||||||
|
int vParentWeight = graph.edgeValueOrDefault(closestEdgeArray[vParent].nodeU(), closestEdgeArray[vParent].nodeV(), 0);
|
||||||
|
|
||||||
|
if (weight < uParentWeight) {
|
||||||
|
closestEdgeArray[uParent] = edge;
|
||||||
|
}
|
||||||
|
if (weight < vParentWeight) {
|
||||||
|
closestEdgeArray[vParent] = edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add newly discovered edges to MST
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
EndpointPair<Integer> edge = closestEdgeArray[i];
|
||||||
|
if (edge != null) {
|
||||||
|
int u = edge.nodeU();
|
||||||
|
int v = edge.nodeV();
|
||||||
|
int weight = graph.edgeValueOrDefault(u, v, 0);
|
||||||
|
// don't add the same edge twice
|
||||||
|
if (uf.find(u) != uf.find(v)) {
|
||||||
|
mst.putEdgeValue(u, v, weight);
|
||||||
|
totalWeight += weight;
|
||||||
|
uf.union(u, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutableValueGraph<Integer, Integer> getMST() {
|
||||||
|
return mst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotalWeight() {
|
||||||
|
return totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
public class UnionFind {
|
||||||
|
private int[] parents;
|
||||||
|
private int[] ranks;
|
||||||
|
|
||||||
|
public UnionFind(int n) {
|
||||||
|
parents = new int[n];
|
||||||
|
ranks = new int[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
parents[i] = i;
|
||||||
|
ranks[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int find(int u) {
|
||||||
|
while (u != parents[u]) {
|
||||||
|
u = parents[u];
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void union(int u, int v) {
|
||||||
|
int uParent = find(u);
|
||||||
|
int vParent = find(v);
|
||||||
|
if (uParent == vParent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ranks[uParent] < ranks[vParent]) {
|
||||||
|
parents[uParent] = vParent;
|
||||||
|
} else if (ranks[uParent] > ranks[vParent]) {
|
||||||
|
parents[vParent] = uParent;
|
||||||
|
} else {
|
||||||
|
parents[vParent] = uParent;
|
||||||
|
ranks[uParent]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.algorithms.gradientdescent;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class GradientDescent {
|
||||||
|
|
||||||
|
private final double precision = 0.000001;
|
||||||
|
|
||||||
|
public double findLocalMinimum(Function<Double, Double> f, double initialX) {
|
||||||
|
double stepCoefficient = 0.1;
|
||||||
|
double previousStep = 1.0;
|
||||||
|
double currentX = initialX;
|
||||||
|
double previousX = initialX;
|
||||||
|
double previousY = f.apply(previousX);
|
||||||
|
int iter = 100;
|
||||||
|
|
||||||
|
currentX += stepCoefficient * previousY;
|
||||||
|
|
||||||
|
while (previousStep > precision && iter > 0) {
|
||||||
|
iter--;
|
||||||
|
double currentY = f.apply(currentX);
|
||||||
|
if (currentY > previousY) {
|
||||||
|
stepCoefficient = -stepCoefficient / 2;
|
||||||
|
}
|
||||||
|
previousX = currentX;
|
||||||
|
currentX += stepCoefficient * previousY;
|
||||||
|
previousY = currentY;
|
||||||
|
previousStep = StrictMath.abs(currentX - previousX);
|
||||||
|
}
|
||||||
|
return currentX;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class LinkedListReversal {
|
||||||
|
|
||||||
|
ListNode reverseList(ListNode head) {
|
||||||
|
ListNode previous = null;
|
||||||
|
ListNode current = head;
|
||||||
|
while (current != null) {
|
||||||
|
ListNode nextElement = current.getNext();
|
||||||
|
current.setNext(previous);
|
||||||
|
previous = current;
|
||||||
|
current = nextElement;
|
||||||
|
}
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode reverseListRecursive(ListNode head) {
|
||||||
|
if (head == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (head.getNext() == null) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
ListNode node = reverseListRecursive(head.getNext());
|
||||||
|
head.getNext().setNext(head);
|
||||||
|
head.setNext(null);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
public class ListNode {
|
||||||
|
|
||||||
|
private int data;
|
||||||
|
private ListNode next;
|
||||||
|
|
||||||
|
ListNode(int data) {
|
||||||
|
this.data = data;
|
||||||
|
this.next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListNode getNext() {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(int data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNext(ListNode next) {
|
||||||
|
this.next = next;
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,13 @@
|
|||||||
package com.baeldung.algorithms.minheapmerge;
|
package com.baeldung.algorithms.minheapmerge;
|
||||||
|
|
||||||
public class HeapNode {
|
public class HeapNode {
|
||||||
|
|
||||||
int element;
|
int element;
|
||||||
int arrayIndex;
|
int arrayIndex;
|
||||||
int nextElementIndex = 1;
|
int nextElementIndex = 1;
|
||||||
|
|
||||||
public HeapNode(int element, int arrayIndex) {
|
public HeapNode(int element, int arrayIndex) {
|
||||||
this.element = element;
|
this.element = element;
|
||||||
this.arrayIndex = arrayIndex;
|
this.arrayIndex = arrayIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,88 +1,88 @@
|
|||||||
package com.baeldung.algorithms.minheapmerge;
|
package com.baeldung.algorithms.minheapmerge;
|
||||||
|
|
||||||
public class MinHeap {
|
public class MinHeap {
|
||||||
|
|
||||||
HeapNode[] heapNodes;
|
HeapNode[] heapNodes;
|
||||||
|
|
||||||
public MinHeap(HeapNode heapNodes[]) {
|
public MinHeap(HeapNode heapNodes[]) {
|
||||||
this.heapNodes = heapNodes;
|
this.heapNodes = heapNodes;
|
||||||
heapifyFromLastLeafsParent();
|
heapifyFromLastLeafsParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void heapifyFromLastLeafsParent() {
|
void heapifyFromLastLeafsParent() {
|
||||||
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
|
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
|
||||||
while (lastLeafsParentIndex >= 0) {
|
while (lastLeafsParentIndex >= 0) {
|
||||||
heapify(lastLeafsParentIndex);
|
heapify(lastLeafsParentIndex);
|
||||||
lastLeafsParentIndex--;
|
lastLeafsParentIndex--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void heapify(int index) {
|
void heapify(int index) {
|
||||||
int leftNodeIndex = getLeftNodeIndex(index);
|
int leftNodeIndex = getLeftNodeIndex(index);
|
||||||
int rightNodeIndex = getRightNodeIndex(index);
|
int rightNodeIndex = getRightNodeIndex(index);
|
||||||
int smallestElementIndex = index;
|
int smallestElementIndex = index;
|
||||||
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
|
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
|
||||||
smallestElementIndex = leftNodeIndex;
|
smallestElementIndex = leftNodeIndex;
|
||||||
}
|
}
|
||||||
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
|
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
|
||||||
smallestElementIndex = rightNodeIndex;
|
smallestElementIndex = rightNodeIndex;
|
||||||
}
|
}
|
||||||
if (smallestElementIndex != index) {
|
if (smallestElementIndex != index) {
|
||||||
swap(index, smallestElementIndex);
|
swap(index, smallestElementIndex);
|
||||||
heapify(smallestElementIndex);
|
heapify(smallestElementIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getParentNodeIndex(int index) {
|
int getParentNodeIndex(int index) {
|
||||||
return (index - 1) / 2;
|
return (index - 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLeftNodeIndex(int index) {
|
int getLeftNodeIndex(int index) {
|
||||||
return (2 * index + 1);
|
return (2 * index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getRightNodeIndex(int index) {
|
int getRightNodeIndex(int index) {
|
||||||
return (2 * index + 2);
|
return (2 * index + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapNode getRootNode() {
|
HeapNode getRootNode() {
|
||||||
return heapNodes[0];
|
return heapNodes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void heapifyFromRoot() {
|
void heapifyFromRoot() {
|
||||||
heapify(0);
|
heapify(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(int i, int j) {
|
void swap(int i, int j) {
|
||||||
HeapNode temp = heapNodes[i];
|
HeapNode temp = heapNodes[i];
|
||||||
heapNodes[i] = heapNodes[j];
|
heapNodes[i] = heapNodes[j];
|
||||||
heapNodes[j] = temp;
|
heapNodes[j] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int[] merge(int[][] array) {
|
static int[] merge(int[][] array) {
|
||||||
HeapNode[] heapNodes = new HeapNode[array.length];
|
HeapNode[] heapNodes = new HeapNode[array.length];
|
||||||
int resultingArraySize = 0;
|
int resultingArraySize = 0;
|
||||||
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
for (int i = 0; i < array.length; i++) {
|
||||||
HeapNode node = new HeapNode(array[i][0], i);
|
HeapNode node = new HeapNode(array[i][0], i);
|
||||||
heapNodes[i] = node;
|
heapNodes[i] = node;
|
||||||
resultingArraySize += array[i].length;
|
resultingArraySize += array[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
MinHeap minHeap = new MinHeap(heapNodes);
|
MinHeap minHeap = new MinHeap(heapNodes);
|
||||||
int[] resultingArray = new int[resultingArraySize];
|
int[] resultingArray = new int[resultingArraySize];
|
||||||
|
|
||||||
for (int i = 0; i < resultingArraySize; i++) {
|
for (int i = 0; i < resultingArraySize; i++) {
|
||||||
HeapNode root = minHeap.getRootNode();
|
HeapNode root = minHeap.getRootNode();
|
||||||
resultingArray[i] = root.element;
|
resultingArray[i] = root.element;
|
||||||
|
|
||||||
if (root.nextElementIndex < array[root.arrayIndex].length) {
|
if (root.nextElementIndex < array[root.arrayIndex].length) {
|
||||||
root.element = array[root.arrayIndex][root.nextElementIndex++];
|
root.element = array[root.arrayIndex][root.nextElementIndex++];
|
||||||
} else {
|
} else {
|
||||||
root.element = Integer.MAX_VALUE;
|
root.element = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
minHeap.heapifyFromRoot();
|
minHeap.heapifyFromRoot();
|
||||||
}
|
}
|
||||||
return resultingArray;
|
return resultingArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,208 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Board {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Board.class);
|
||||||
|
|
||||||
|
private final int[][] board;
|
||||||
|
|
||||||
|
private final int score;
|
||||||
|
|
||||||
|
public Board(int size) {
|
||||||
|
assert(size > 0);
|
||||||
|
|
||||||
|
this.board = new int[size][];
|
||||||
|
this.score = 0;
|
||||||
|
|
||||||
|
for (int x = 0; x < size; ++x) {
|
||||||
|
this.board[x] = new int[size];
|
||||||
|
for (int y = 0; y < size; ++y) {
|
||||||
|
board[x][y] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Board(int[][] board, int score) {
|
||||||
|
this.score = score;
|
||||||
|
this.board = new int[board.length][];
|
||||||
|
|
||||||
|
for (int x = 0; x < board.length; ++x) {
|
||||||
|
this.board[x] = Arrays.copyOf(board[x], board[x].length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return board.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCell(Cell cell) {
|
||||||
|
int x = cell.getX();
|
||||||
|
int y = cell.getY();
|
||||||
|
assert(x >= 0 && x < board.length);
|
||||||
|
assert(y >= 0 && y < board.length);
|
||||||
|
|
||||||
|
return board[x][y];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty(Cell cell) {
|
||||||
|
return getCell(cell) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Cell> emptyCells() {
|
||||||
|
List<Cell> result = new ArrayList<>();
|
||||||
|
for (int x = 0; x < board.length; ++x) {
|
||||||
|
for (int y = 0; y < board[x].length; ++y) {
|
||||||
|
Cell cell = new Cell(x, y);
|
||||||
|
if (isEmpty(cell)) {
|
||||||
|
result.add(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board placeTile(Cell cell, int number) {
|
||||||
|
if (!isEmpty(cell)) {
|
||||||
|
throw new IllegalArgumentException("That cell is not empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
Board result = new Board(this.board, this.score);
|
||||||
|
result.board[cell.getX()][cell.getY()] = number;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board move(Move move) {
|
||||||
|
// Clone the board
|
||||||
|
int[][] tiles = new int[this.board.length][];
|
||||||
|
for (int x = 0; x < this.board.length; ++x) {
|
||||||
|
tiles[x] = Arrays.copyOf(this.board[x], this.board[x].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Before move: {}", Arrays.deepToString(tiles));
|
||||||
|
// If we're doing an Left/Right move then transpose the board to make it a Up/Down move
|
||||||
|
if (move == Move.LEFT || move == Move.RIGHT) {
|
||||||
|
tiles = transpose(tiles);
|
||||||
|
LOG.debug("After transpose: {}", Arrays.deepToString(tiles));
|
||||||
|
}
|
||||||
|
// If we're doing a Right/Down move then reverse the board.
|
||||||
|
// With the above we're now always doing an Up move
|
||||||
|
if (move == Move.DOWN || move == Move.RIGHT) {
|
||||||
|
tiles = reverse(tiles);
|
||||||
|
LOG.debug("After reverse: {}", Arrays.deepToString(tiles));
|
||||||
|
}
|
||||||
|
LOG.debug("Ready to move: {}", Arrays.deepToString(tiles));
|
||||||
|
|
||||||
|
// Shift everything up
|
||||||
|
int[][] result = new int[tiles.length][];
|
||||||
|
int newScore = 0;
|
||||||
|
for (int x = 0; x < tiles.length; ++x) {
|
||||||
|
LinkedList<Integer> thisRow = new LinkedList<>();
|
||||||
|
for (int y = 0; y < tiles[0].length; ++y) {
|
||||||
|
if (tiles[x][y] > 0) {
|
||||||
|
thisRow.add(tiles[x][y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Unmerged row: {}", thisRow);
|
||||||
|
LinkedList<Integer> newRow = new LinkedList<>();
|
||||||
|
while (thisRow.size() >= 2) {
|
||||||
|
int first = thisRow.pop();
|
||||||
|
int second = thisRow.peek();
|
||||||
|
LOG.debug("Looking at numbers {} and {}", first, second);
|
||||||
|
if (second == first) {
|
||||||
|
LOG.debug("Numbers match, combining");
|
||||||
|
int newNumber = first * 2;
|
||||||
|
newRow.add(newNumber);
|
||||||
|
newScore += newNumber;
|
||||||
|
thisRow.pop();
|
||||||
|
} else {
|
||||||
|
LOG.debug("Numbers don't match");
|
||||||
|
newRow.add(first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newRow.addAll(thisRow);
|
||||||
|
LOG.debug("Merged row: {}", newRow);
|
||||||
|
|
||||||
|
result[x] = new int[tiles[0].length];
|
||||||
|
for (int y = 0; y < tiles[0].length; ++y) {
|
||||||
|
if (newRow.isEmpty()) {
|
||||||
|
result[x][y] = 0;
|
||||||
|
} else {
|
||||||
|
result[x][y] = newRow.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG.debug("After moves: {}", Arrays.deepToString(result));
|
||||||
|
|
||||||
|
// Un-reverse the board
|
||||||
|
if (move == Move.DOWN || move == Move.RIGHT) {
|
||||||
|
result = reverse(result);
|
||||||
|
LOG.debug("After reverse: {}", Arrays.deepToString(result));
|
||||||
|
}
|
||||||
|
// Un-transpose the board
|
||||||
|
if (move == Move.LEFT || move == Move.RIGHT) {
|
||||||
|
result = transpose(result);
|
||||||
|
LOG.debug("After transpose: {}", Arrays.deepToString(result));
|
||||||
|
}
|
||||||
|
return new Board(result, this.score + newScore);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[][] transpose(int[][] input) {
|
||||||
|
int[][] result = new int[input.length][];
|
||||||
|
|
||||||
|
for (int x = 0; x < input.length; ++x) {
|
||||||
|
result[x] = new int[input[0].length];
|
||||||
|
for (int y = 0; y < input[0].length; ++y) {
|
||||||
|
result[x][y] = input[y][x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int[][] reverse(int[][] input) {
|
||||||
|
int[][] result = new int[input.length][];
|
||||||
|
|
||||||
|
for (int x = 0; x < input.length; ++x) {
|
||||||
|
result[x] = new int[input[0].length];
|
||||||
|
for (int y = 0; y < input[0].length; ++y) {
|
||||||
|
result[x][y] = input[x][input.length - y - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Arrays.deepToString(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Board board1 = (Board) o;
|
||||||
|
return Arrays.deepEquals(board, board1.board);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Arrays.deepHashCode(board);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class Cell {
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
|
public Cell(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new StringJoiner(", ", Cell.class.getSimpleName() + "[", "]").add("x=" + x).add("y=" + y).toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Computer {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Computer.class);
|
||||||
|
|
||||||
|
private final SecureRandom rng = new SecureRandom();
|
||||||
|
|
||||||
|
public Board makeMove(Board input) {
|
||||||
|
List<Cell> emptyCells = input.emptyCells();
|
||||||
|
LOG.info("Number of empty cells: {}", emptyCells.size());
|
||||||
|
|
||||||
|
double numberToPlace = rng.nextDouble();
|
||||||
|
LOG.info("New number probability: {}", numberToPlace);
|
||||||
|
|
||||||
|
int indexToPlace = rng.nextInt(emptyCells.size());
|
||||||
|
Cell cellToPlace = emptyCells.get(indexToPlace);
|
||||||
|
LOG.info("Placing number into empty cell: {}", cellToPlace);
|
||||||
|
|
||||||
|
return input.placeTile(cellToPlace, numberToPlace >= 0.9 ? 4 : 2);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.apache.commons.math3.util.Pair;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class Human {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Human.class);
|
||||||
|
|
||||||
|
public Board makeMove(Board input) {
|
||||||
|
// For each move in MOVE
|
||||||
|
// Generate board from move
|
||||||
|
// Generate Score for Board
|
||||||
|
// Return board with the best score
|
||||||
|
//
|
||||||
|
// Generate Score
|
||||||
|
// If Depth Limit
|
||||||
|
// Return Final Score
|
||||||
|
// Total Score = 0
|
||||||
|
// For every empty square in new board
|
||||||
|
// Generate board with "2" in square
|
||||||
|
// Calculate Score
|
||||||
|
// Total Score += (Score * 0.9)
|
||||||
|
// Generate board with "4" in square
|
||||||
|
// Calculate Score
|
||||||
|
// Total Score += (Score * 0.1)
|
||||||
|
//
|
||||||
|
// Calculate Score
|
||||||
|
// For each move in MOVE
|
||||||
|
// Generate board from move
|
||||||
|
// Generate score for board
|
||||||
|
// Return the best generated score
|
||||||
|
|
||||||
|
return Arrays.stream(Move.values())
|
||||||
|
.parallel()
|
||||||
|
.map(input::move)
|
||||||
|
.filter(board -> !board.equals(input))
|
||||||
|
.max(Comparator.comparingInt(board -> generateScore(board, 0)))
|
||||||
|
.orElse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int generateScore(Board board, int depth) {
|
||||||
|
if (depth >= 3) {
|
||||||
|
int finalScore = calculateFinalScore(board);
|
||||||
|
LOG.debug("Final score for board {}: {}", board,finalScore);
|
||||||
|
return finalScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
return board.emptyCells().stream()
|
||||||
|
.parallel()
|
||||||
|
.flatMap(cell -> Stream.of(new Pair<>(cell, 2), new Pair<>(cell, 4)))
|
||||||
|
.mapToInt(move -> {
|
||||||
|
LOG.debug("Simulating move {} at depth {}", move, depth);
|
||||||
|
Board newBoard = board.placeTile(move.getFirst(), move.getSecond());
|
||||||
|
int boardScore = calculateScore(newBoard, depth + 1);
|
||||||
|
int calculatedScore = (int) (boardScore * (move.getSecond() == 2 ? 0.9 : 0.1));
|
||||||
|
LOG.debug("Calculated score for board {} and move {} at depth {}: {}", newBoard, move, depth, calculatedScore);
|
||||||
|
return calculatedScore;
|
||||||
|
})
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateScore(Board board, int depth) {
|
||||||
|
return Arrays.stream(Move.values())
|
||||||
|
.parallel()
|
||||||
|
.map(board::move)
|
||||||
|
.filter(moved -> !moved.equals(board))
|
||||||
|
.mapToInt(newBoard -> generateScore(newBoard, depth))
|
||||||
|
.max()
|
||||||
|
.orElse(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculateFinalScore(Board board) {
|
||||||
|
List<List<Integer>> rowsToScore = new ArrayList<>();
|
||||||
|
for (int i = 0; i < board.getSize(); ++i) {
|
||||||
|
List<Integer> row = new ArrayList<>();
|
||||||
|
List<Integer> col = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int j = 0; j < board.getSize(); ++j) {
|
||||||
|
row.add(board.getCell(new Cell(i, j)));
|
||||||
|
col.add(board.getCell(new Cell(j, i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
rowsToScore.add(row);
|
||||||
|
rowsToScore.add(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowsToScore.stream()
|
||||||
|
.parallel()
|
||||||
|
.mapToInt(row -> {
|
||||||
|
List<Integer> preMerged = row.stream()
|
||||||
|
.filter(value -> value != 0)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
int numMerges = 0;
|
||||||
|
int monotonicityLeft = 0;
|
||||||
|
int monotonicityRight = 0;
|
||||||
|
for (int i = 0; i < preMerged.size() - 1; ++i) {
|
||||||
|
Integer first = preMerged.get(i);
|
||||||
|
Integer second = preMerged.get(i + 1);
|
||||||
|
if (first.equals(second)) {
|
||||||
|
++numMerges;
|
||||||
|
} else if (first > second) {
|
||||||
|
monotonicityLeft += first - second;
|
||||||
|
} else {
|
||||||
|
monotonicityRight += second - first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int score = 1000;
|
||||||
|
score += 250 * row.stream().filter(value -> value == 0).count();
|
||||||
|
score += 750 * numMerges;
|
||||||
|
score -= 10 * row.stream().mapToInt(value -> value).sum();
|
||||||
|
score -= 50 * Math.min(monotonicityLeft, monotonicityRight);
|
||||||
|
return score;
|
||||||
|
})
|
||||||
|
.sum();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
public enum Move {
|
||||||
|
UP,
|
||||||
|
DOWN,
|
||||||
|
LEFT,
|
||||||
|
RIGHT
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.baeldung.algorithms.play2048;
|
||||||
|
|
||||||
|
public class Play2048 {
|
||||||
|
private static final int SIZE = 4;
|
||||||
|
private static final int INITIAL_NUMBERS = 2;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// The board and players
|
||||||
|
Board board = new Board(SIZE);
|
||||||
|
Computer computer = new Computer();
|
||||||
|
Human human = new Human();
|
||||||
|
|
||||||
|
// The computer has two moves first
|
||||||
|
System.out.println("Setup");
|
||||||
|
System.out.println("=====");
|
||||||
|
for (int i = 0; i < INITIAL_NUMBERS; ++i) {
|
||||||
|
board = computer.makeMove(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
printBoard(board);
|
||||||
|
do {
|
||||||
|
board = human.makeMove(board);
|
||||||
|
System.out.println("Human move");
|
||||||
|
System.out.println("==========");
|
||||||
|
printBoard(board);
|
||||||
|
|
||||||
|
board = computer.makeMove(board);
|
||||||
|
System.out.println("Computer move");
|
||||||
|
System.out.println("=============");
|
||||||
|
printBoard(board);
|
||||||
|
} while (!board.emptyCells().isEmpty());
|
||||||
|
|
||||||
|
System.out.println("Final Score: " + board.getScore());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printBoard(Board board) {
|
||||||
|
StringBuilder topLines = new StringBuilder();
|
||||||
|
StringBuilder midLines = new StringBuilder();
|
||||||
|
for (int x = 0; x < board.getSize(); ++x) {
|
||||||
|
topLines.append("+--------");
|
||||||
|
midLines.append("| ");
|
||||||
|
}
|
||||||
|
topLines.append("+");
|
||||||
|
midLines.append("|");
|
||||||
|
|
||||||
|
|
||||||
|
for (int y = 0; y < board.getSize(); ++y) {
|
||||||
|
System.out.println(topLines);
|
||||||
|
System.out.println(midLines);
|
||||||
|
for (int x = 0; x < board.getSize(); ++x) {
|
||||||
|
Cell cell = new Cell(x, y);
|
||||||
|
System.out.print("|");
|
||||||
|
if (board.isEmpty(cell)) {
|
||||||
|
System.out.print(" ");
|
||||||
|
} else {
|
||||||
|
StringBuilder output = new StringBuilder(Integer.toString(board.getCell(cell)));
|
||||||
|
while (output.length() < 8) {
|
||||||
|
output.append(" ");
|
||||||
|
if (output.length() < 8) {
|
||||||
|
output.insert(0, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.print(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("|");
|
||||||
|
System.out.println(midLines);
|
||||||
|
}
|
||||||
|
System.out.println(topLines);
|
||||||
|
System.out.println("Score: " + board.getScore());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.algorithms.topkelements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BruteForceTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||||
|
|
||||||
|
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||||
|
List<Integer> array = new ArrayList<>(input);
|
||||||
|
List<Integer> topKList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < k; i++) {
|
||||||
|
int maxIndex = 0;
|
||||||
|
|
||||||
|
for (int j = 1; j < array.size(); j++) {
|
||||||
|
if (array.get(j) > array.get(maxIndex)) {
|
||||||
|
maxIndex = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topKList.add(array.remove(maxIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return topKList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.baeldung.algorithms.topkelements;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
public class MaxHeapTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||||
|
|
||||||
|
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||||
|
PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
|
||||||
|
|
||||||
|
input.forEach(number -> {
|
||||||
|
maxHeap.add(number);
|
||||||
|
|
||||||
|
if (maxHeap.size() > k) {
|
||||||
|
maxHeap.poll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<Integer> topKList = new ArrayList<>(maxHeap);
|
||||||
|
Collections.reverse(topKList);
|
||||||
|
|
||||||
|
return topKList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.baeldung.algorithms.topkelements;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface TopKElementsFinder<T extends Comparable<T>> {
|
||||||
|
List<T> findTopK(List<T> input, int k);
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.baeldung.algorithms.topkelements;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class TreeSetTopKElementsFinder implements TopKElementsFinder<Integer> {
|
||||||
|
|
||||||
|
public List<Integer> findTopK(List<Integer> input, int k) {
|
||||||
|
Set<Integer> sortedSet = new TreeSet<>(Comparator.reverseOrder());
|
||||||
|
sortedSet.addAll(input);
|
||||||
|
|
||||||
|
return sortedSet.stream().limit(k).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.algorithms.boruvka;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.google.common.graph.MutableValueGraph;
|
||||||
|
import com.google.common.graph.ValueGraphBuilder;
|
||||||
|
|
||||||
|
public class BoruvkaUnitTest {
|
||||||
|
|
||||||
|
private MutableValueGraph<Integer, Integer> graph;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
graph = ValueGraphBuilder.undirected()
|
||||||
|
.build();
|
||||||
|
graph.putEdgeValue(0, 1, 8);
|
||||||
|
graph.putEdgeValue(0, 2, 5);
|
||||||
|
graph.putEdgeValue(1, 2, 9);
|
||||||
|
graph.putEdgeValue(1, 3, 11);
|
||||||
|
graph.putEdgeValue(2, 3, 15);
|
||||||
|
graph.putEdgeValue(2, 4, 10);
|
||||||
|
graph.putEdgeValue(3, 4, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() {
|
||||||
|
BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
|
||||||
|
MutableValueGraph<Integer, Integer> mst = boruvkaMST.getMST();
|
||||||
|
|
||||||
|
assertEquals(30, boruvkaMST.getTotalWeight());
|
||||||
|
assertEquals(4, mst.edges().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.algorithms.gradientdescent;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class GradientDescentUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFunction_whenStartingPointIsOne_thenLocalMinimumIsFound() {
|
||||||
|
Function<Double, Double> df = x ->
|
||||||
|
StrictMath.abs(StrictMath.pow(x, 3)) - (3 * StrictMath.pow(x, 2)) + x;
|
||||||
|
GradientDescent gd = new GradientDescent();
|
||||||
|
double res = gd.findLocalMinimum(df, 1);
|
||||||
|
assertTrue(res > 1.78);
|
||||||
|
assertTrue(res < 1.84);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.algorithms.linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
public class LinkedListReversalUnitTest {
|
||||||
|
@Test
|
||||||
|
public void givenLinkedList_whenIterativeReverse_thenOutputCorrectResult() {
|
||||||
|
ListNode head = constructLinkedList();
|
||||||
|
ListNode node = head;
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
assertNotNull(node);
|
||||||
|
assertEquals(i, node.getData());
|
||||||
|
node = node.getNext();
|
||||||
|
}
|
||||||
|
LinkedListReversal reversal = new LinkedListReversal();
|
||||||
|
node = reversal.reverseList(head);
|
||||||
|
for (int i = 5; i >= 1; i--) {
|
||||||
|
assertNotNull(node);
|
||||||
|
assertEquals(i, node.getData());
|
||||||
|
node = node.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLinkedList_whenRecursiveReverse_thenOutputCorrectResult() {
|
||||||
|
ListNode head = constructLinkedList();
|
||||||
|
ListNode node = head;
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
assertNotNull(node);
|
||||||
|
assertEquals(i, node.getData());
|
||||||
|
node = node.getNext();
|
||||||
|
}
|
||||||
|
LinkedListReversal reversal = new LinkedListReversal();
|
||||||
|
node = reversal.reverseListRecursive(head);
|
||||||
|
for (int i = 5; i >= 1; i--) {
|
||||||
|
assertNotNull(node);
|
||||||
|
assertEquals(i, node.getData());
|
||||||
|
node = node.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListNode constructLinkedList() {
|
||||||
|
ListNode head = null;
|
||||||
|
ListNode tail = null;
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
ListNode node = new ListNode(i);
|
||||||
|
if (head == null) {
|
||||||
|
head = node;
|
||||||
|
} else {
|
||||||
|
tail.setNext(node);
|
||||||
|
}
|
||||||
|
tail = node;
|
||||||
|
}
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,22 @@
|
|||||||
package com.baeldung.algorithms.minheapmerge;
|
package com.baeldung.algorithms.minheapmerge;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class MinHeapUnitTest {
|
public class MinHeapUnitTest {
|
||||||
|
|
||||||
private final int[][] inputArray = { { 0, 6 }, { 1, 5, 10, 100 }, { 2, 4, 200, 650 } };
|
private final int[][] inputArray = { { 0, 6 }, { 1, 5, 10, 100 }, { 2, 4, 200, 650 } };
|
||||||
private final int[] expectedArray = { 0, 1, 2, 4, 5, 6, 10, 100, 200, 650 };
|
private final int[] expectedArray = { 0, 1, 2, 4, 5, 6, 10, 100, 200, 650 };
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenSortedArrays_whenMerged_thenShouldReturnASingleSortedarray() {
|
public void givenSortedArrays_whenMerged_thenShouldReturnASingleSortedarray() {
|
||||||
int[] resultArray = MinHeap.merge(inputArray);
|
int[] resultArray = MinHeap.merge(inputArray);
|
||||||
|
|
||||||
assertThat(resultArray.length, is(equalTo(10)));
|
assertThat(resultArray.length, is(equalTo(10)));
|
||||||
assertThat(resultArray, is(equalTo(expectedArray)));
|
assertThat(resultArray, is(equalTo(expectedArray)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.baeldung.algorithms.topkelements;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||||
|
|
||||||
|
public class TopKElementsFinderUnitTest {
|
||||||
|
private final TopKElementsFinder<Integer> bruteForceFinder = new BruteForceTopKElementsFinder();
|
||||||
|
private final TopKElementsFinder<Integer> maxHeapFinder = new MaxHeapTopKElementsFinder();
|
||||||
|
private final TopKElementsFinder<Integer> treeSetFinder = new TreeSetTopKElementsFinder();
|
||||||
|
|
||||||
|
private final int k = 4;
|
||||||
|
private final List<Integer> distinctIntegers = Arrays.asList(1, 2, 3, 9, 7, 6, 12);
|
||||||
|
private final List<Integer> distinctIntegersTopK = Arrays.asList(9, 7, 6, 12);
|
||||||
|
private final List<Integer> nonDistinctIntegers = Arrays.asList(1, 2, 3, 3, 9, 9, 7, 6, 12);
|
||||||
|
private final List<Integer> nonDistinctIntegersTopK = Arrays.asList(9, 9, 7, 12);
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayDistinctIntegers_whenBruteForceFindTopK_thenReturnKLargest() {
|
||||||
|
assertThat(bruteForceFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayDistinctIntegers_whenMaxHeapFindTopK_thenReturnKLargest() {
|
||||||
|
assertThat(maxHeapFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayDistinctIntegers_whenTreeSetFindTopK_thenReturnKLargest() {
|
||||||
|
assertThat(treeSetFinder.findTopK(distinctIntegers, k)).containsOnlyElementsOf(distinctIntegersTopK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayNonDistinctIntegers_whenBruteForceFindTopK_thenReturnKLargest() {
|
||||||
|
assertThat(bruteForceFinder.findTopK(nonDistinctIntegers, k)).containsOnlyElementsOf(nonDistinctIntegersTopK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenArrayNonDistinctIntegers_whenMaxHeapFindTopK_thenReturnKLargest() {
|
||||||
|
assertThat(maxHeapFinder.findTopK(nonDistinctIntegers, k)).containsOnlyElementsOf(nonDistinctIntegersTopK);
|
||||||
|
}
|
||||||
|
}
|
@ -3,10 +3,13 @@
|
|||||||
This module contains articles about searching algorithms.
|
This module contains articles about searching algorithms.
|
||||||
|
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
- [Binary Search Algorithm in Java](https://www.baeldung.com/java-binary-search)
|
- [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)
|
- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search)
|
||||||
- [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-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)
|
- [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)
|
- [String Search Algorithms for Large Texts with Java](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)
|
- [Monte Carlo Tree Search for Tic-Tac-Toe Game in Java](https://www.baeldung.com/java-monte-carlo-tree-search)
|
||||||
- [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search)
|
- [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search)
|
||||||
|
- [Fast Pattern Matching of Strings Using Suffix Tree in Java](https://www.baeldung.com/java-pattern-matching-suffix-tree)
|
||||||
|
- [Find the Kth Smallest Element in Two Sorted Arrays in Java](https://www.baeldung.com/java-kth-smallest-element-in-sorted-arrays)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-searching</artifactId>
|
<artifactId>algorithms-searching</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.baeldung.algorithms.kthsmallest;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import static java.lang.Math.max;
|
||||||
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
|
public class KthSmallest {
|
||||||
|
|
||||||
|
public static int findKthSmallestElement(int k, int[] list1, int[] list2) throws NoSuchElementException, IllegalArgumentException {
|
||||||
|
|
||||||
|
checkInput(k, list1, list2);
|
||||||
|
|
||||||
|
// we are looking for the minimum value
|
||||||
|
if(k == 1) {
|
||||||
|
return min(list1[0], list2[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we are looking for the maximum value
|
||||||
|
if(list1.length + list2.length == k) {
|
||||||
|
return max(list1[list1.length-1], list2[list2.length-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// swap lists if needed to make sure we take at least one element from list1
|
||||||
|
if(k <= list2.length && list2[k-1] < list1[0]) {
|
||||||
|
int[] list1_ = list1;
|
||||||
|
list1 = list2;
|
||||||
|
list2 = list1_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// correct left boundary if k is bigger than the size of list2
|
||||||
|
int left = k < list2.length ? 0 : k - list2.length - 1;
|
||||||
|
|
||||||
|
// the inital right boundary cannot exceed the list1
|
||||||
|
int right = min(k-1, list1.length - 1);
|
||||||
|
|
||||||
|
int nElementsList1, nElementsList2;
|
||||||
|
|
||||||
|
// binary search
|
||||||
|
do {
|
||||||
|
nElementsList1 = ((left + right) / 2) + 1;
|
||||||
|
nElementsList2 = k - nElementsList1;
|
||||||
|
|
||||||
|
if(nElementsList2 > 0) {
|
||||||
|
if (list1[nElementsList1 - 1] > list2[nElementsList2 - 1]) {
|
||||||
|
right = nElementsList1 - 2;
|
||||||
|
} else {
|
||||||
|
left = nElementsList1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(!kthSmallesElementFound(list1, list2, nElementsList1, nElementsList2));
|
||||||
|
|
||||||
|
return nElementsList2 == 0 ? list1[nElementsList1-1] : max(list1[nElementsList1-1], list2[nElementsList2-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean kthSmallesElementFound(int[] list1, int[] list2, int nElementsList1, int nElementsList2) {
|
||||||
|
|
||||||
|
// we do not take any element from the second list
|
||||||
|
if(nElementsList2 < 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(list1[nElementsList1-1] == list2[nElementsList2-1]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElementsList1 == list1.length) {
|
||||||
|
return list1[nElementsList1-1] <= list2[nElementsList2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nElementsList2 == list2.length) {
|
||||||
|
return list2[nElementsList2-1] <= list1[nElementsList1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return list1[nElementsList1-1] <= list2[nElementsList2] && list2[nElementsList2-1] <= list1[nElementsList1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void checkInput(int k, int[] list1, int[] list2) throws NoSuchElementException, IllegalArgumentException {
|
||||||
|
|
||||||
|
if(list1 == null || list2 == null || k < 1) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(list1.length == 0 || list2.length == 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(k > list1.length + list2.length) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getKthElementSorted(int[] list1, int[] list2, int k) {
|
||||||
|
|
||||||
|
int length1 = list1.length, length2 = list2.length;
|
||||||
|
int[] combinedArray = new int[length1 + length2];
|
||||||
|
System.arraycopy(list1, 0, combinedArray, 0, list1.length);
|
||||||
|
System.arraycopy(list2, 0, combinedArray, list1.length, list2.length);
|
||||||
|
Arrays.sort(combinedArray);
|
||||||
|
|
||||||
|
return combinedArray[k-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getKthElementMerge(int[] list1, int[] list2, int k) {
|
||||||
|
|
||||||
|
int i1 = 0, i2 = 0;
|
||||||
|
|
||||||
|
while(i1 < list1.length && i2 < list2.length && (i1 + i2) < k) {
|
||||||
|
if(list1[i1] < list2[i2]) {
|
||||||
|
i1++;
|
||||||
|
} else {
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if((i1 + i2) < k) {
|
||||||
|
return i1 < list1.length ? list1[k - i2 - 1] : list2[k - i1 - 1];
|
||||||
|
} else if(i1 > 0 && i2 > 0) {
|
||||||
|
return Math.max(list1[i1-1], list2[i2-1]);
|
||||||
|
} else {
|
||||||
|
return i1 == 0 ? list2[i2-1] : list1[i1-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,288 @@
|
|||||||
|
package com.baeldung.algorithms.kthsmallest;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.function.Executable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static com.baeldung.algorithms.kthsmallest.KthSmallest.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class KthSmallestUnitTest {
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Exceptions {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_at_least_one_list_is_null_then_an_exception_is_thrown() {
|
||||||
|
|
||||||
|
Executable executable1 = () -> findKthSmallestElement(1, null, null);
|
||||||
|
Executable executable2 = () -> findKthSmallestElement(1, new int[]{2}, null);
|
||||||
|
Executable executable3 = () -> findKthSmallestElement(1, null, new int[]{2});
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException.class, executable1);
|
||||||
|
assertThrows(IllegalArgumentException.class, executable2);
|
||||||
|
assertThrows(IllegalArgumentException.class, executable3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_at_least_one_list_is_empty_then_an_exception_is_thrown() {
|
||||||
|
|
||||||
|
Executable executable1 = () -> findKthSmallestElement(1, new int[]{}, new int[]{2});
|
||||||
|
Executable executable2 = () -> findKthSmallestElement(1, new int[]{2}, new int[]{});
|
||||||
|
Executable executable3 = () -> findKthSmallestElement(1, new int[]{}, new int[]{});
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException.class, executable1);
|
||||||
|
assertThrows(IllegalArgumentException.class, executable2);
|
||||||
|
assertThrows(IllegalArgumentException.class, executable3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_smaller_than_0_then_an_exception_is_thrown() {
|
||||||
|
Executable executable1 = () -> findKthSmallestElement(-1, new int[]{2}, new int[]{2});
|
||||||
|
assertThrows(IllegalArgumentException.class, executable1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_smaller_than_1_then_an_exception_is_thrown() {
|
||||||
|
Executable executable1 = () -> findKthSmallestElement(0, new int[]{2}, new int[]{2});
|
||||||
|
assertThrows(IllegalArgumentException.class, executable1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_bigger_then_the_two_lists_then_an_exception_is_thrown() {
|
||||||
|
Executable executable1 = () -> findKthSmallestElement(6, new int[]{1, 5, 6}, new int[]{2, 5});
|
||||||
|
assertThrows(NoSuchElementException.class, executable1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class K_is_smaller_than_the_size_of_list1_and_the_size_of_list2 {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_1_then_the_smallest_element_is_returned_from_list1() {
|
||||||
|
int result = findKthSmallestElement(1, new int[]{2, 7}, new int[]{3, 5});
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_1_then_the_smallest_element_is_returned_list2() {
|
||||||
|
int result = findKthSmallestElement(1, new int[]{3, 5}, new int[]{2, 7});
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_kth_element_is_smallest_element_and_occurs_in_both_lists() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(1, list1, list2);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_kth_element_is_smallest_element_and_occurs_in_both_lists2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(2, list1, list2);
|
||||||
|
assertEquals(1, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_kth_element_is_largest_element_and_occurs_in_both_lists_1() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(5, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_kth_element_is_largest_element_and_occurs_in_both_lists_2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(6, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_kth_element_and_occurs_in_both_lists() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{0, 2, 3};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_kth_element_is_in_first_list() {
|
||||||
|
int[] list1 = new int[]{1,2,3,4};
|
||||||
|
int[] list2 = new int[]{1,3,4,5};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_kth_is_in_second_list() {
|
||||||
|
int[] list1 = new int[]{1,3,4,4};
|
||||||
|
int[] list2 = new int[]{1,2,4,5};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(2, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_elements_in_first_list_are_all_smaller_than_second_list() {
|
||||||
|
int[] list1 = new int[]{1,3,7,9};
|
||||||
|
int[] list2 = new int[]{11,12,14,15};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(7, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_elements_in_first_list_are_all_smaller_than_second_list2() {
|
||||||
|
int[] list1 = new int[]{1,3,7,9};
|
||||||
|
int[] list2 = new int[]{11,12,14,15};
|
||||||
|
int result = findKthSmallestElement(4, list1, list2);
|
||||||
|
assertEquals(9, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_only_elements_from_second_list_are_part_of_result() {
|
||||||
|
int[] list1 = new int[]{11,12,14,15};
|
||||||
|
int[] list2 = new int[]{1,3,7,9};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(7, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void and_only_elements_from_second_list_are_part_of_result2() {
|
||||||
|
int[] list1 = new int[]{11,12,14,15};
|
||||||
|
int[] list2 = new int[]{1,3,7,9};
|
||||||
|
int result = findKthSmallestElement(4, list1, list2);
|
||||||
|
assertEquals(9, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class K_is_bigger_than_the_size_of_at_least_one_of_the_lists {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void k_is_smaller_than_list1_and_bigger_than_list2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3, 4, 7, 9};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(5, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void k_is_bigger_than_list1_and_smaller_than_list2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3};
|
||||||
|
int[] list2 = new int[]{1, 2, 3, 4, 7, 9};
|
||||||
|
int result = findKthSmallestElement(5, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_bigger_than_the_size_of_both_lists_and_elements_in_second_list_are_all_smaller_than_first_list() {
|
||||||
|
int[] list1 = new int[]{9, 11, 13, 55};
|
||||||
|
int[] list2 = new int[]{1, 2, 3, 7};
|
||||||
|
int result = findKthSmallestElement(6, list1, list2);
|
||||||
|
assertEquals(11, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_bigger_than_the_size_of_both_lists_and_elements_in_second_list_are_all_bigger_than_first_list() {
|
||||||
|
int[] list1 = new int[]{1, 2, 3, 7};
|
||||||
|
int[] list2 = new int[]{9, 11, 13, 55};
|
||||||
|
int result = findKthSmallestElement(6, list1, list2);
|
||||||
|
assertEquals(11, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_bigger_than_the_size_of_both_lists() {
|
||||||
|
int[] list1 = new int[]{3, 7, 9, 11, 55};
|
||||||
|
int[] list2 = new int[]{1, 2, 3, 7, 13};
|
||||||
|
int result = findKthSmallestElement(7, list1, list2);
|
||||||
|
assertEquals(9, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_bigger_than_the_size_of_both_lists_and_list1_has_more_elements_than_list2() {
|
||||||
|
int[] list1 = new int[]{3, 7, 9, 11, 55, 77, 100, 200};
|
||||||
|
int[] list2 = new int[]{1, 2, 3, 7, 13};
|
||||||
|
int result = findKthSmallestElement(11, list1, list2);
|
||||||
|
assertEquals(77, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void max_test() {
|
||||||
|
int[] list1 = new int[]{100, 200};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(4, list1, list2);
|
||||||
|
assertEquals(100, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void max_test2() {
|
||||||
|
int[] list1 = new int[]{100, 200};
|
||||||
|
int[] list2 = new int[]{1, 2, 3};
|
||||||
|
int result = findKthSmallestElement(5, list1, list2);
|
||||||
|
assertEquals(200, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_smaller_than_the_size_of_both_lists_and_kth_element_in_list2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 5};
|
||||||
|
int[] list2 = new int[]{1, 3, 4, 7};
|
||||||
|
int result = findKthSmallestElement(4, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_smaller_than_the_size_of_both_lists_and_kth_element_is_smallest_in_list2() {
|
||||||
|
int[] list1 = new int[]{1, 2, 5};
|
||||||
|
int[] list2 = new int[]{3, 4, 7};
|
||||||
|
int result = findKthSmallestElement(3, list1, list2);
|
||||||
|
assertEquals(3, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void when_k_is_smaller_than_the_size_of_both_lists_and_kth_element_is_smallest_in_list23() {
|
||||||
|
int[] list1 = new int[]{3, 11, 27, 53, 90};
|
||||||
|
int[] list2 = new int[]{4, 20, 21, 100};
|
||||||
|
int result = findKthSmallestElement(5, list1, list2);
|
||||||
|
assertEquals(21, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void randomTests() {
|
||||||
|
// IntStream.range(1, 100000).forEach(i -> random());
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void random() {
|
||||||
|
|
||||||
|
Random random = new Random();
|
||||||
|
int length1 = (Math.abs(random.nextInt())) % 1000 + 1;
|
||||||
|
int length2 = (Math.abs(random.nextInt())) % 1000 + 1;
|
||||||
|
|
||||||
|
int[] list1 = sortedRandomIntArrayOfLength(length1);
|
||||||
|
int[] list2 = sortedRandomIntArrayOfLength(length2);
|
||||||
|
|
||||||
|
int k = (Math.abs(random.nextInt()) % (length1 + length2)) + 1 ;
|
||||||
|
|
||||||
|
int result = findKthSmallestElement(k, list1, list2);
|
||||||
|
|
||||||
|
int result2 = getKthElementSorted(list1, list2, k);
|
||||||
|
|
||||||
|
int result3 = getKthElementMerge(list1, list2, k);
|
||||||
|
|
||||||
|
assertEquals(result2, result);
|
||||||
|
assertEquals(result2, result3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] sortedRandomIntArrayOfLength(int length) {
|
||||||
|
int[] intArray = new Random().ints(length).toArray();
|
||||||
|
Arrays.sort(intArray);
|
||||||
|
return intArray;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
|
|
||||||
- [Partitioning and Sorting Arrays with Many Repeated Entries](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
|
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
|
||||||
|
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||||
|
- [Guide to In-Place Sorting Algorithm Works with a Java Implementation](https://www.baeldung.com/java-in-place-sorting)
|
||||||
|
- [Partitioning and Sorting Arrays with Many Repeated Entries with Java Examples](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
|
||||||
|
- More articles: [[<-- prev]](/algorithms-sorting)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-sorting-2</artifactId>
|
<artifactId>algorithms-sorting-2</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package com.baeldung.algorithms.sort.bynumber;
|
package com.baeldung.algorithms.bynumber;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
@ -5,21 +5,21 @@ import static com.baeldung.algorithms.quicksort.SortingUtils.swap;
|
|||||||
|
|
||||||
public class DutchNationalFlagPartioning {
|
public class DutchNationalFlagPartioning {
|
||||||
|
|
||||||
public static Partition partition(int[] a, int begin, int end) {
|
public static Partition partition(int[] input, int begin, int end) {
|
||||||
int lt = begin, current = begin, gt = end;
|
int lt = begin, current = begin, gt = end;
|
||||||
int partitioningValue = a[begin];
|
int partitioningValue = input[begin];
|
||||||
|
|
||||||
while (current <= gt) {
|
while (current <= gt) {
|
||||||
int compareCurrent = compare(a[current], partitioningValue);
|
int compareCurrent = compare(input[current], partitioningValue);
|
||||||
switch (compareCurrent) {
|
switch (compareCurrent) {
|
||||||
case -1:
|
case -1:
|
||||||
swap(a, current++, lt++);
|
swap(input, current++, lt++);
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
current++;
|
current++;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
swap(a, current, gt--);
|
swap(input, current, gt--);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.baeldung.algorithms.sort.bynumber;
|
package com.baeldung.algorithms.bynumber;
|
||||||
|
|
||||||
import com.baeldung.algorithms.sort.bynumber.NaturalOrderComparators;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
@ -11,10 +11,7 @@ This module contains articles about sorting algorithms.
|
|||||||
- [Heap Sort in Java](https://www.baeldung.com/java-heap-sort)
|
- [Heap Sort in Java](https://www.baeldung.com/java-heap-sort)
|
||||||
- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort)
|
- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort)
|
||||||
- [Counting Sort in Java](https://www.baeldung.com/java-counting-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)
|
- [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)
|
- [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)
|
- [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort)
|
||||||
|
- More articles: [[next -->]](/algorithms-sorintg-2)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>algorithms-sorting</artifactId>
|
<artifactId>algorithms-sorting</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
@ -44,5 +46,5 @@
|
|||||||
<animal-sniffer-maven-plugin.version>1.16</animal-sniffer-maven-plugin.version>
|
<animal-sniffer-maven-plugin.version>1.16</animal-sniffer-maven-plugin.version>
|
||||||
<org.codehaus.mojo.signature.java16.version>1.0</org.codehaus.mojo.signature.java16.version>
|
<org.codehaus.mojo.signature.java16.version>1.0</org.codehaus.mojo.signature.java16.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>annotation-processing</artifactId>
|
<artifactId>annotation-processing</artifactId>
|
||||||
<name>annotation-processing</name>
|
<name>annotation-processing</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>annotation-user</artifactId>
|
<artifactId>annotation-user</artifactId>
|
||||||
<name>annotation-user</name>
|
<name>annotation-user</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<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"
|
||||||
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<name>annotations</name>
|
<name>annotations</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>antlr</artifactId>
|
<artifactId>antlr</artifactId>
|
||||||
<name>antlr</name>
|
<name>antlr</name>
|
||||||
@ -58,5 +60,5 @@
|
|||||||
<antlr.version>4.7.1</antlr.version>
|
<antlr.version>4.7.1</antlr.version>
|
||||||
<mojo.version>3.0.0</mojo.version>
|
<mojo.version>3.0.0</mojo.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
@ -1,6 +0,0 @@
|
|||||||
## Apache Avro
|
|
||||||
|
|
||||||
This module contains articles about Apache Avro
|
|
||||||
|
|
||||||
### Relevant Articles:
|
|
||||||
- [Guide to Apache Avro](https://www.baeldung.com/java-apache-avro)
|
|
@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>apache-avro</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<name>apache-avro</name>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>${slf4j.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.avro</groupId>
|
|
||||||
<artifactId>avro</artifactId>
|
|
||||||
<version>${avro.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.avro</groupId>
|
|
||||||
<artifactId>avro-compiler</artifactId>
|
|
||||||
<version>${avro.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.avro</groupId>
|
|
||||||
<artifactId>avro-maven-plugin</artifactId>
|
|
||||||
<version>${avro.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.avro</groupId>
|
|
||||||
<artifactId>avro-maven-plugin</artifactId>
|
|
||||||
<version>${avro.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>schemas</id>
|
|
||||||
<phase>generate-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>schema</goal>
|
|
||||||
<goal>protocol</goal>
|
|
||||||
<goal>idl-protocol</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
|
|
||||||
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<avro.version>1.8.2</avro.version>
|
|
||||||
<slf4j.version>1.7.25</slf4j.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,43 +0,0 @@
|
|||||||
<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>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<groupId>com.baeldung.apache</groupId>
|
|
||||||
<artifactId>apache-beam</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.beam</groupId>
|
|
||||||
<artifactId>beam-sdks-java-core</artifactId>
|
|
||||||
<version>${beam.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- runtime scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.beam</groupId>
|
|
||||||
<artifactId>beam-runners-direct-java</artifactId>
|
|
||||||
<version>${beam.version}</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- test scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<beam.version>2.19.0</beam.version>
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,7 +0,0 @@
|
|||||||
## Apache BVal
|
|
||||||
|
|
||||||
This module contains articles about Apache BVal
|
|
||||||
|
|
||||||
### Relevant Articles:
|
|
||||||
|
|
||||||
- [Intro to Apache BVal](https://www.baeldung.com/apache-bval)
|
|
@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>apache-bval</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<name>apache-bval</name>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.bval</groupId>
|
|
||||||
<artifactId>bval-jsr</artifactId>
|
|
||||||
<version>${bval.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.validation</groupId>
|
|
||||||
<artifactId>validation-api</artifactId>
|
|
||||||
<version>${javax.validation.validation-api.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.bval</groupId>
|
|
||||||
<artifactId>bval-extras</artifactId>
|
|
||||||
<version>${bval.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<bval.version>1.1.2</bval.version>
|
|
||||||
<javax.validation.validation-api.version>1.1.0.Final</javax.validation.validation-api.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,120 +0,0 @@
|
|||||||
package com.baeldung.model;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
|
|
||||||
import org.apache.bval.constraints.Email;
|
|
||||||
import org.apache.bval.constraints.NotEmpty;
|
|
||||||
import org.apache.bval.extras.constraints.checkdigit.IBAN;
|
|
||||||
import org.apache.bval.extras.constraints.creditcard.Visa;
|
|
||||||
import org.apache.bval.extras.constraints.file.Directory;
|
|
||||||
import org.apache.bval.extras.constraints.net.InetAddress;
|
|
||||||
|
|
||||||
import com.baeldung.validation.Password;
|
|
||||||
|
|
||||||
public class User {
|
|
||||||
@NotNull
|
|
||||||
@Email
|
|
||||||
private String email;
|
|
||||||
|
|
||||||
@NotEmpty
|
|
||||||
@Password
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@Size(min = 1, max = 20)
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
@Min(18)
|
|
||||||
private int age;
|
|
||||||
|
|
||||||
@Visa
|
|
||||||
private String cardNumber = "";
|
|
||||||
|
|
||||||
@IBAN
|
|
||||||
private String iban = "";
|
|
||||||
|
|
||||||
@InetAddress
|
|
||||||
private String website = "";
|
|
||||||
|
|
||||||
@Directory
|
|
||||||
private File mainDirectory=new File(".");
|
|
||||||
|
|
||||||
public User() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public User(String email, String password, String name, int age) {
|
|
||||||
super();
|
|
||||||
this.email = email;
|
|
||||||
this.password = password;
|
|
||||||
this.name = name;
|
|
||||||
this.age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEmail() {
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmail(String email) {
|
|
||||||
this.email = email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String password) {
|
|
||||||
this.password = password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAge() {
|
|
||||||
return age;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAge(int age) {
|
|
||||||
this.age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCardNumber() {
|
|
||||||
return cardNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCardNumber(String cardNumber) {
|
|
||||||
this.cardNumber = cardNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIban() {
|
|
||||||
return iban;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIban(String iban) {
|
|
||||||
this.iban = iban;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getWebsite() {
|
|
||||||
return website;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWebsite(String website) {
|
|
||||||
this.website = website;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File getMainDirectory() {
|
|
||||||
return mainDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMainDirectory(File mainDirectory) {
|
|
||||||
this.mainDirectory = mainDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
## Apache Curator
|
|
||||||
|
|
||||||
This module contains articles about Apache Curator
|
|
||||||
|
|
||||||
### Relevant Articles:
|
|
||||||
|
|
||||||
- [Introduction to Apache Curator](https://www.baeldung.com/apache-curator)
|
|
@ -1,68 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>apache-curator</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<name>apache-curator</name>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>parent-modules</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- curator -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.curator</groupId>
|
|
||||||
<artifactId>curator-x-async</artifactId>
|
|
||||||
<version>${curator.version}</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.apache.zookeeper</groupId>
|
|
||||||
<artifactId>zookeeper</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.curator</groupId>
|
|
||||||
<artifactId>curator-recipes</artifactId>
|
|
||||||
<version>${curator.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.zookeeper</groupId>
|
|
||||||
<artifactId>zookeeper</artifactId>
|
|
||||||
<version>${zookeeper.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- utils -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- test scoped -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jayway.awaitility</groupId>
|
|
||||||
<artifactId>awaitility</artifactId>
|
|
||||||
<version>${avaitility.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<curator.version>4.0.1</curator.version>
|
|
||||||
<zookeeper.version>3.4.11</zookeeper.version>
|
|
||||||
<!-- testing -->
|
|
||||||
<assertj.version>3.6.1</assertj.version>
|
|
||||||
<avaitility.version>1.7.0</avaitility.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
</project>
|
|
@ -3,8 +3,7 @@
|
|||||||
This module contains articles about Apache CXF
|
This module contains articles about Apache CXF
|
||||||
|
|
||||||
## Relevant Articles:
|
## Relevant Articles:
|
||||||
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
|
||||||
- [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api)
|
- [Apache CXF Support for RESTful Web Services](https://www.baeldung.com/apache-cxf-rest-api)
|
||||||
- [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring)
|
- [A Guide to Apache CXF with Spring](https://www.baeldung.com/apache-cxf-with-spring)
|
||||||
- [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf)
|
- [Introduction to Apache CXF](https://www.baeldung.com/introduction-to-apache-cxf)
|
||||||
- [Server-Sent Events (SSE) In JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse)
|
|
||||||
|
3
apache-cxf/cxf-aegis/README.md
Normal file
3
apache-cxf/cxf-aegis/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Introduction to Apache CXF Aegis Data Binding](https://www.baeldung.com/aegis-data-binding-in-apache-cxf)
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>cxf-aegis</artifactId>
|
<artifactId>cxf-aegis</artifactId>
|
||||||
<name>cxf-aegis</name>
|
<name>cxf-aegis</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>cxf-introduction</artifactId>
|
<artifactId>cxf-introduction</artifactId>
|
||||||
<name>cxf-introduction</name>
|
<name>cxf-introduction</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>cxf-jaxrs-implementation</artifactId>
|
<artifactId>cxf-jaxrs-implementation</artifactId>
|
||||||
<name>cxf-jaxrs-implementation</name>
|
<name>cxf-jaxrs-implementation</name>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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"
|
<project
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>cxf-spring</artifactId>
|
<artifactId>cxf-spring</artifactId>
|
||||||
<name>cxf-spring</name>
|
<name>cxf-spring</name>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user