Merge remote-tracking branch 'origin/BAEL-3985' into BAEL-3985
This commit is contained in:
commit
fbefae05ec
|
@ -39,7 +39,6 @@ target/
|
|||
spring-openid/src/main/resources/application.properties
|
||||
.recommenders/
|
||||
/spring-hibernate4/nbproject/
|
||||
spring-security-openid/src/main/resources/application.properties
|
||||
|
||||
spring-all/*.log
|
||||
|
||||
|
@ -66,6 +65,7 @@ core-java-io/target_link.txt
|
|||
core-java/src/main/java/com/baeldung/manifest/MANIFEST.MF
|
||||
ethereum/logs/
|
||||
jmeter/src/main/resources/*-JMeter.csv
|
||||
ninja/devDb.mv.db
|
||||
|
||||
**/node_modules/
|
||||
**/dist
|
||||
|
@ -73,8 +73,6 @@ jmeter/src/main/resources/*-JMeter.csv
|
|||
**/out-tsc
|
||||
**/nbproject/
|
||||
**/nb-configuration.xml
|
||||
core-scala/.cache-main
|
||||
core-scala/.cache-tests
|
||||
|
||||
|
||||
persistence-modules/hibernate5/transaction.log
|
||||
|
|
44
README.md
44
README.md
|
@ -22,10 +22,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.
|
||||
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
|
||||
====================
|
||||
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
|
||||
|
@ -46,8 +74,18 @@ When you're working with an individual module, there's no need to import all of
|
|||
|
||||
Running Tests
|
||||
=============
|
||||
The command `mvn clean install` will run the unit tests in a module.
|
||||
To run the integration tests, use the command `mvn clean install -Pintegration-lite-first`
|
||||
The command `mvn clean install` from within a module will run the unit tests in that module.
|
||||
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"?>
|
||||
<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">
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>akka-http</artifactId>
|
||||
<name>akka-http</name>
|
||||
|
|
|
@ -7,6 +7,8 @@ import akka.http.javadsl.model.HttpEntities;
|
|||
import akka.http.javadsl.model.HttpRequest;
|
||||
import akka.http.javadsl.testkit.JUnitRouteTest;
|
||||
import akka.http.javadsl.testkit.TestRoute;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UserServerUnitTest extends JUnitRouteTest {
|
||||
|
@ -17,6 +19,7 @@ public class UserServerUnitTest extends JUnitRouteTest {
|
|||
|
||||
TestRoute appRoute = testRoute(new UserServer(userActorRef).routes());
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void whenRequest_thenActorResponds() {
|
||||
|
||||
|
@ -28,10 +31,10 @@ public class UserServerUnitTest extends JUnitRouteTest {
|
|||
.assertStatusCode(404);
|
||||
|
||||
appRoute.run(HttpRequest.DELETE("/users/1"))
|
||||
.assertStatusCode(200);
|
||||
.assertStatusCode(405);
|
||||
|
||||
appRoute.run(HttpRequest.DELETE("/users/42"))
|
||||
.assertStatusCode(200);
|
||||
.assertStatusCode(405);
|
||||
|
||||
appRoute.run(HttpRequest.POST("/users")
|
||||
.withEntity(HttpEntities.create(ContentTypes.APPLICATION_JSON, zaphod())))
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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>akka-streams</artifactId>
|
||||
<name>akka-streams</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-genetic</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-1</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
@ -64,7 +66,7 @@
|
|||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>cobertura-maven-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
<version>${cobertura.plugin.version}</version>
|
||||
<configuration>
|
||||
<instrumentation>
|
||||
<ignores>
|
||||
|
@ -85,6 +87,7 @@
|
|||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
<combinatoricslib3.version>3.3.0</combinatoricslib3.version>
|
||||
<cobertura.plugin.version>2.7</cobertura.plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -13,4 +13,5 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||
- [Create a Sudoku Solver in Java](https://www.baeldung.com/java-sudoku)
|
||||
- [Displaying Money Amounts in Words](https://www.baeldung.com/java-money-into-words)
|
||||
- [A Collaborative Filtering Recommendation System in Java](https://www.baeldung.com/java-collaborative-filtering-recommendations)
|
||||
- [Implementing A* Pathfinding in Java](https://www.baeldung.com/java-a-star-pathfinding)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-1) [[next -->]](/../algorithms-miscellaneous-3)
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
|
@ -98,7 +98,7 @@ public class SlopeOne {
|
|||
for (Item j : InputData.items) {
|
||||
if (e.getValue().containsKey(j)) {
|
||||
clean.put(j, e.getValue().get(j));
|
||||
} else {
|
||||
} else if (!clean.containsKey(j)) {
|
||||
clean.put(j, -1.0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +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)
|
||||
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
|
||||
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
|
||||
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
|
||||
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
|
||||
- [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation)
|
||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
@ -46,13 +48,13 @@
|
|||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>${commons.lang3.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>pl.pragmatists</groupId>
|
||||
<artifactId>JUnitParams</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>${JUnitParams.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -91,6 +93,8 @@
|
|||
<retrofit.version>2.6.0</retrofit.version>
|
||||
<jmh-core.version>1.19</jmh-core.version>
|
||||
<jmh-generator.version>1.19</jmh-generator.version>
|
||||
<commons.lang3.version>3.8.1</commons.lang3.version>
|
||||
<JUnitParams.version>1.1.0</JUnitParams.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>algorithms-miscellaneous-4</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
|
@ -10,4 +10,10 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
|
|||
- [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers)
|
||||
- [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack)
|
||||
- [How to Determine if a Binary Tree is Balanced](https://www.baeldung.com/java-balanced-binary-tree)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4)
|
||||
- [Overview of Combinatorial Problems in Java](https://www.baeldung.com/java-combinatorial-algorithms)
|
||||
- [Prim’s Algorithm](https://www.baeldung.com/java-prim-algorithm)
|
||||
- [Maximum Subarray Problem](https://www.baeldung.com/java-maximum-subarray)
|
||||
- [How to Merge Two Sorted Arrays](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)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-4) [[next -->]](/../algorithms-miscellaneous-6)
|
||||
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>algorithms-miscellaneous-5</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
@ -23,17 +25,21 @@
|
|||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>pl.allegro.finance</groupId>
|
||||
<artifactId>tradukisto</artifactId>
|
||||
<version>${tradukisto.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>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>
|
||||
|
@ -60,6 +66,8 @@
|
|||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<guava.version>28.1-jre</guava.version>
|
||||
<junit.platform.version>1.6.0</junit.platform.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,20 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class Follower {
|
||||
|
||||
@Getter String username;
|
||||
@Getter long count;
|
||||
|
||||
public Follower(String username, long count) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User: " + username + ", Followers: " + count + "\n\r" ;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FollowersPath {
|
||||
|
||||
private List<Follower> accounts;
|
||||
private long count;
|
||||
|
||||
public FollowersPath() {
|
||||
super();
|
||||
this.accounts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<Follower> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void addFollower(String username, long count) {
|
||||
accounts.add(new Follower(username, count));
|
||||
}
|
||||
|
||||
public void addCount(long count) {
|
||||
this.count += count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String details = "";
|
||||
for(Follower a : accounts) {
|
||||
details+=a.toString() + ", ";
|
||||
}
|
||||
|
||||
return "Total: " + count + ", \n\r" +
|
||||
" Details: { " + "\n\r" +
|
||||
details + "\n\r" +
|
||||
" }";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GreedyAlgorithm {
|
||||
|
||||
int currentLevel = 0;
|
||||
final int maxLevel = 3;
|
||||
SocialConnector sc;
|
||||
FollowersPath fp;
|
||||
|
||||
public GreedyAlgorithm(SocialConnector sc) {
|
||||
super();
|
||||
this.sc = sc;
|
||||
this.fp = new FollowersPath();
|
||||
}
|
||||
|
||||
public long findMostFollowersPath(String account) throws Exception {
|
||||
long max = 0;
|
||||
SocialUser toFollow = null;
|
||||
|
||||
List<SocialUser> followers = sc.getFollowers(account);
|
||||
for (SocialUser el : followers) {
|
||||
long followersCount = el.getFollowersCount();
|
||||
if (followersCount > max) {
|
||||
toFollow = el;
|
||||
max = followersCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLevel < maxLevel - 1) {
|
||||
currentLevel++;
|
||||
max += findMostFollowersPath(toFollow.getUsername());
|
||||
//fp.addFollower(toFollow.getUsername(), max);
|
||||
//fp.addCount(max);
|
||||
return max;
|
||||
} else {
|
||||
//fp.addFollower(toFollow.getUsername(), max);
|
||||
//fp.addCount(max);
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
public FollowersPath getFollowers() {
|
||||
return fp;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NonGreedyAlgorithm {
|
||||
|
||||
int currentLevel = 0;
|
||||
final int maxLevel = 3;
|
||||
SocialConnector tc;
|
||||
|
||||
public NonGreedyAlgorithm(SocialConnector tc, int level) {
|
||||
super();
|
||||
this.tc = tc;
|
||||
this.currentLevel = level;
|
||||
}
|
||||
|
||||
|
||||
public long findMostFollowersPath(String account) throws Exception {
|
||||
List<SocialUser> followers = tc.getFollowers(account);
|
||||
long total = currentLevel > 0 ? followers.size() : 0;
|
||||
|
||||
if (currentLevel < maxLevel ) {
|
||||
currentLevel++;
|
||||
|
||||
long[] count = new long[followers.size()];
|
||||
int i = 0;
|
||||
for (SocialUser el : followers) {
|
||||
NonGreedyAlgorithm sub = new NonGreedyAlgorithm(tc, currentLevel);
|
||||
count[i] = sub.findMostFollowersPath(el.getUsername());
|
||||
i++;
|
||||
}
|
||||
|
||||
long max = 0;
|
||||
for (; i > 0; i--) {
|
||||
if (count[i-1] > max )
|
||||
max = count[i-1];
|
||||
}
|
||||
|
||||
return total + max;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class SocialConnector {
|
||||
private boolean isCounterEnabled = true;
|
||||
private int counter = 4;
|
||||
@Getter @Setter List<SocialUser> users;
|
||||
|
||||
public SocialConnector() {
|
||||
users = new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean switchCounter() {
|
||||
this.isCounterEnabled = !this.isCounterEnabled;
|
||||
return this.isCounterEnabled;
|
||||
}
|
||||
|
||||
public List<SocialUser> getFollowers(String account) throws Exception {
|
||||
if (counter < 0)
|
||||
throw new Exception ("API limit reached");
|
||||
else {
|
||||
if(this.isCounterEnabled) counter--;
|
||||
for(SocialUser user : users) {
|
||||
if (user.getUsername().equals(account)) {
|
||||
return user.getFollowers();
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class SocialUser {
|
||||
|
||||
@Getter private String username;
|
||||
@Getter private List<SocialUser> followers;
|
||||
|
||||
public SocialUser(String username) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.followers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public SocialUser(String username, List<SocialUser> followers) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.followers = followers;
|
||||
}
|
||||
|
||||
public long getFollowersCount() {
|
||||
return followers.size();
|
||||
}
|
||||
|
||||
public void addFollowers(List<SocialUser> followers) {
|
||||
this.followers.addAll(followers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return ((SocialUser) obj).getUsername().equals(username);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.algorithms.integerstreammedian;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
|
||||
public class MedianOfIntegerStream {
|
||||
|
||||
private Queue<Integer> minHeap, maxHeap;
|
||||
|
||||
MedianOfIntegerStream() {
|
||||
minHeap = new PriorityQueue<>();
|
||||
maxHeap = new PriorityQueue<>(reverseOrder());
|
||||
}
|
||||
|
||||
void add(int num) {
|
||||
if (!minHeap.isEmpty() && num < minHeap.peek()) {
|
||||
maxHeap.offer(num);
|
||||
if (maxHeap.size() > minHeap.size() + 1) {
|
||||
minHeap.offer(maxHeap.poll());
|
||||
}
|
||||
} else {
|
||||
minHeap.offer(num);
|
||||
if (minHeap.size() > maxHeap.size() + 1) {
|
||||
maxHeap.offer(minHeap.poll());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double getMedian() {
|
||||
int median;
|
||||
if (minHeap.size() < maxHeap.size()) {
|
||||
median = maxHeap.peek();
|
||||
} else if (minHeap.size() > maxHeap.size()) {
|
||||
median = minHeap.peek();
|
||||
} else {
|
||||
median = (minHeap.peek() + maxHeap.peek()) / 2;
|
||||
}
|
||||
return median;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.algorithms.integerstreammedian;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
|
||||
import static java.util.Comparator.reverseOrder;
|
||||
|
||||
public class MedianOfIntegerStream2 {
|
||||
|
||||
private Queue<Integer> minHeap, maxHeap;
|
||||
|
||||
MedianOfIntegerStream2() {
|
||||
minHeap = new PriorityQueue<>();
|
||||
maxHeap = new PriorityQueue<>(reverseOrder());
|
||||
}
|
||||
|
||||
void add(int num) {
|
||||
if (minHeap.size() == maxHeap.size()) {
|
||||
maxHeap.offer(num);
|
||||
minHeap.offer(maxHeap.poll());
|
||||
} else {
|
||||
minHeap.offer(num);
|
||||
maxHeap.offer(minHeap.poll());
|
||||
}
|
||||
}
|
||||
|
||||
double getMedian() {
|
||||
int median;
|
||||
if (minHeap.size() > maxHeap.size()) {
|
||||
median = minHeap.peek();
|
||||
} else {
|
||||
median = (minHeap.peek() + maxHeap.peek()) / 2;
|
||||
}
|
||||
return median;
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class GreedyAlgorithmUnitTest {
|
||||
|
||||
private SocialConnector prepareNetwork() {
|
||||
SocialConnector sc = new SocialConnector();
|
||||
|
||||
SocialUser root = new SocialUser("root");
|
||||
SocialUser child1 = new SocialUser("child1");
|
||||
SocialUser child2 = new SocialUser("child2");
|
||||
SocialUser child3 = new SocialUser("child3");
|
||||
SocialUser child21 = new SocialUser("child21");
|
||||
SocialUser child211 = new SocialUser("child211");
|
||||
SocialUser child2111 = new SocialUser("child2111");
|
||||
SocialUser child31 = new SocialUser("child31");
|
||||
SocialUser child311 = new SocialUser("child311");
|
||||
SocialUser child3111 = new SocialUser("child3111");
|
||||
|
||||
|
||||
child211.addFollowers(Arrays.asList(new SocialUser[]{child2111}));
|
||||
child311.addFollowers(Arrays.asList(new SocialUser[]{child3111}));
|
||||
|
||||
child21.addFollowers(Arrays.asList(new SocialUser[]{child211}));
|
||||
child31.addFollowers(Arrays.asList(new SocialUser[]{child311,
|
||||
new SocialUser("child312"), new SocialUser("child313"), new SocialUser("child314")}));
|
||||
|
||||
child1.addFollowers(Arrays.asList(new SocialUser[]{new SocialUser("child11"), new SocialUser("child12")}));
|
||||
child2.addFollowers(Arrays.asList(new SocialUser[]{child21, new SocialUser("child22"), new SocialUser("child23")}));
|
||||
child3.addFollowers(Arrays.asList(new SocialUser[]{child31}));
|
||||
|
||||
root.addFollowers(Arrays.asList(new SocialUser[]{child1, child2, child3}));
|
||||
|
||||
sc.setUsers(Arrays.asList(new SocialUser[]{root, child1, child2, child3, child21, child31, child311, child211}));
|
||||
return sc;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void greedyAlgorithmTest() throws Exception {
|
||||
GreedyAlgorithm ga = new GreedyAlgorithm(prepareNetwork());
|
||||
assertEquals(ga.findMostFollowersPath("root"), 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nongreedyAlgorithmTest() throws Exception {
|
||||
NonGreedyAlgorithm nga = new NonGreedyAlgorithm(prepareNetwork(), 0);
|
||||
Assertions.assertThrows(Exception.class, () -> {
|
||||
nga.findMostFollowersPath("root");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nongreedyAlgorithmUnboundedTest() throws Exception {
|
||||
SocialConnector sc = prepareNetwork();
|
||||
sc.switchCounter();
|
||||
NonGreedyAlgorithm nga = new NonGreedyAlgorithm(sc, 0);
|
||||
assertEquals(nga.findMostFollowersPath("root"), 6);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.algorithms.integerstreammedian;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class MedianOfIntegerStreamUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenStreamOfIntegers_whenAnElementIsRead_thenMedianChangesWithApproach1() {
|
||||
MedianOfIntegerStream mis = new MedianOfIntegerStream();
|
||||
for (Map.Entry<Integer, Double> e : testcaseFixture().entrySet()) {
|
||||
mis.add(e.getKey());
|
||||
assertEquals(e.getValue(), (Double) mis.getMedian());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStreamOfIntegers_whenAnElementIsRead_thenMedianChangesWithApproach2() {
|
||||
MedianOfIntegerStream2 mis = new MedianOfIntegerStream2();
|
||||
for (Map.Entry<Integer, Double> e : testcaseFixture().entrySet()) {
|
||||
mis.add(e.getKey());
|
||||
assertEquals(e.getValue(), (Double) mis.getMedian());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Integer, Double> testcaseFixture() {
|
||||
return new LinkedHashMap<Integer, Double>() {{
|
||||
put(1, 1d);
|
||||
put(7, 4d);
|
||||
put(5, 5d);
|
||||
put(8, 6d);
|
||||
put(3, 5d);
|
||||
put(9, 6d);
|
||||
put(4, 5d);
|
||||
}};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"nodes": 5,
|
||||
"edges": 7,
|
||||
"edgeList": [
|
||||
{
|
||||
"first": 0,
|
||||
"second": 1,
|
||||
"weight": 8
|
||||
},
|
||||
{
|
||||
"first": 0,
|
||||
"second": 2,
|
||||
"weight": 5
|
||||
},
|
||||
{
|
||||
"first": 1,
|
||||
"second": 2,
|
||||
"weight": 9
|
||||
},
|
||||
{
|
||||
"first": 1,
|
||||
"second": 3,
|
||||
"weight": 11
|
||||
},
|
||||
{
|
||||
"first": 2,
|
||||
"second": 3,
|
||||
"weight": 15
|
||||
},
|
||||
{
|
||||
"first": 2,
|
||||
"second": 4,
|
||||
"weight": 10
|
||||
},
|
||||
{
|
||||
"first": 3,
|
||||
"second": 4,
|
||||
"weight": 7
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Boruvka’s Algorithm for Minimum Spanning Trees](https://www.baeldung.com/java-boruvka-algorithm)
|
||||
- [Gradient Descent in Java](https://www.baeldung.com/java-gradient-descent)
|
||||
- [Kruskal’s Algorithm for Spanning Trees](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)
|
||||
- More articles: [[<-- prev]](/../algorithms-miscellaneous-5)
|
|
@ -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,36 @@
|
|||
package com.baeldung.algorithms.balancedbrackets;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class BalancedBracketsUsingDeque {
|
||||
|
||||
public boolean isBalanced(String str) {
|
||||
if (null == str || ((str.length() % 2) != 0)) {
|
||||
return false;
|
||||
} else {
|
||||
char[] ch = str.toCharArray();
|
||||
for (char c : ch) {
|
||||
if (!(c == '{' || c == '[' || c == '(' || c == '}' || c == ']' || c == ')')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Deque<Character> deque = new LinkedList<>();
|
||||
for (char ch : str.toCharArray()) {
|
||||
if (ch == '{' || ch == '[' || ch == '(') {
|
||||
deque.addFirst(ch);
|
||||
} else {
|
||||
if (!deque.isEmpty() && ((deque.peekFirst() == '{' && ch == '}') || (deque.peekFirst() == '[' && ch == ']') || (deque.peekFirst() == '(' && ch == ')'))) {
|
||||
deque.removeFirst();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.baeldung.algorithms.balancedbrackets;
|
||||
|
||||
public class BalancedBracketsUsingString {
|
||||
|
||||
public boolean isBalanced(String str) {
|
||||
if (null == str || ((str.length() % 2) != 0)) {
|
||||
return false;
|
||||
} else {
|
||||
char[] ch = str.toCharArray();
|
||||
for (char c : ch) {
|
||||
if (!(c == '{' || c == '[' || c == '(' || c == '}' || c == ']' || c == ')')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
while (str.contains("()") || str.contains("[]") || str.contains("{}")) {
|
||||
str = str.replaceAll("\\(\\)", "")
|
||||
.replaceAll("\\[\\]", "")
|
||||
.replaceAll("\\{\\}", "");
|
||||
}
|
||||
return (str.length() == 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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,20 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class Follower {
|
||||
|
||||
@Getter String username;
|
||||
@Getter long count;
|
||||
|
||||
public Follower(String username, long count) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User: " + username + ", Followers: " + count + "\n\r" ;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FollowersPath {
|
||||
|
||||
private List<Follower> accounts;
|
||||
private long count;
|
||||
|
||||
public FollowersPath() {
|
||||
super();
|
||||
this.accounts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<Follower> getAccounts() {
|
||||
return accounts;
|
||||
}
|
||||
public long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void addFollower(String username, long count) {
|
||||
accounts.add(new Follower(username, count));
|
||||
}
|
||||
|
||||
public void addCount(long count) {
|
||||
this.count += count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String details = "";
|
||||
for(Follower a : accounts) {
|
||||
details+=a.toString() + ", ";
|
||||
}
|
||||
|
||||
return "Total: " + count + ", \n\r" +
|
||||
" Details: { " + "\n\r" +
|
||||
details + "\n\r" +
|
||||
" }";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GreedyAlgorithm {
|
||||
|
||||
int currentLevel = 0;
|
||||
final int maxLevel = 3;
|
||||
SocialConnector sc;
|
||||
FollowersPath fp;
|
||||
|
||||
public GreedyAlgorithm(SocialConnector sc) {
|
||||
super();
|
||||
this.sc = sc;
|
||||
this.fp = new FollowersPath();
|
||||
}
|
||||
|
||||
public long findMostFollowersPath(String account) {
|
||||
long max = 0;
|
||||
SocialUser toFollow = null;
|
||||
|
||||
List<SocialUser> followers = sc.getFollowers(account);
|
||||
for (SocialUser el : followers) {
|
||||
long followersCount = el.getFollowersCount();
|
||||
if (followersCount > max) {
|
||||
toFollow = el;
|
||||
max = followersCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLevel < maxLevel - 1) {
|
||||
currentLevel++;
|
||||
max += findMostFollowersPath(toFollow.getUsername());
|
||||
return max;
|
||||
} else {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
|
||||
public FollowersPath getFollowers() {
|
||||
return fp;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NonGreedyAlgorithm {
|
||||
|
||||
int currentLevel = 0;
|
||||
final int maxLevel = 3;
|
||||
SocialConnector tc;
|
||||
|
||||
public NonGreedyAlgorithm(SocialConnector tc, int level) {
|
||||
super();
|
||||
this.tc = tc;
|
||||
this.currentLevel = level;
|
||||
}
|
||||
|
||||
public long findMostFollowersPath(String account) {
|
||||
List<SocialUser> followers = tc.getFollowers(account);
|
||||
long total = currentLevel > 0 ? followers.size() : 0;
|
||||
|
||||
if (currentLevel < maxLevel ) {
|
||||
currentLevel++;
|
||||
|
||||
long[] count = new long[followers.size()];
|
||||
int i = 0;
|
||||
for (SocialUser el : followers) {
|
||||
NonGreedyAlgorithm sub = new NonGreedyAlgorithm(tc, currentLevel);
|
||||
count[i] = sub.findMostFollowersPath(el.getUsername());
|
||||
i++;
|
||||
}
|
||||
|
||||
long max = 0;
|
||||
for (; i > 0; i--) {
|
||||
if (count[i-1] > max )
|
||||
max = count[i-1];
|
||||
}
|
||||
|
||||
return total + max;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class SocialConnector {
|
||||
private boolean isCounterEnabled = true;
|
||||
private int counter = 4;
|
||||
@Getter @Setter List<SocialUser> users;
|
||||
|
||||
public SocialConnector() {
|
||||
users = new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean switchCounter() {
|
||||
this.isCounterEnabled = !this.isCounterEnabled;
|
||||
return this.isCounterEnabled;
|
||||
}
|
||||
|
||||
public List<SocialUser> getFollowers(String account) {
|
||||
if (counter < 0)
|
||||
throw new IllegalStateException ("API limit reached");
|
||||
else {
|
||||
if(this.isCounterEnabled) counter--;
|
||||
for(SocialUser user : users) {
|
||||
if (user.getUsername().equals(account)) {
|
||||
return user.getFollowers();
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
public class SocialUser {
|
||||
|
||||
@Getter private String username;
|
||||
@Getter private List<SocialUser> followers;
|
||||
|
||||
public SocialUser(String username) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.followers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public SocialUser(String username, List<SocialUser> followers) {
|
||||
super();
|
||||
this.username = username;
|
||||
this.followers = followers;
|
||||
}
|
||||
|
||||
public long getFollowersCount() {
|
||||
return followers.size();
|
||||
}
|
||||
|
||||
public void addFollowers(List<SocialUser> followers) {
|
||||
this.followers.addAll(followers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return ((SocialUser) obj).getUsername().equals(username);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package com.baeldung.algorithms.kruskal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CycleDetector {
|
||||
|
||||
List<DisjointSetInfo> nodes;
|
||||
|
||||
public CycleDetector(int totalNodes) {
|
||||
initDisjointSets(totalNodes);
|
||||
}
|
||||
|
||||
public boolean detectCycle(Integer u, Integer v) {
|
||||
Integer rootU = pathCompressionFind(u);
|
||||
Integer rootV = pathCompressionFind(v);
|
||||
if (rootU.equals(rootV)) {
|
||||
return true;
|
||||
}
|
||||
unionByRank(rootU, rootV);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void initDisjointSets(int totalNodes) {
|
||||
nodes = new ArrayList<>(totalNodes);
|
||||
for (int i = 0; i < totalNodes; i++) {
|
||||
nodes.add(new DisjointSetInfo(i));
|
||||
}
|
||||
}
|
||||
|
||||
private Integer find(Integer node) {
|
||||
Integer parent = nodes.get(node).getParentNode();
|
||||
if (parent.equals(node)) {
|
||||
return node;
|
||||
} else {
|
||||
return find(parent);
|
||||
}
|
||||
}
|
||||
|
||||
private Integer pathCompressionFind(Integer node) {
|
||||
DisjointSetInfo setInfo = nodes.get(node);
|
||||
Integer parent = setInfo.getParentNode();
|
||||
if (parent.equals(node)) {
|
||||
return node;
|
||||
} else {
|
||||
Integer parentNode = find(parent);
|
||||
setInfo.setParentNode(parentNode);
|
||||
return parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
private void union(Integer rootU, Integer rootV) {
|
||||
DisjointSetInfo setInfoU = nodes.get(rootU);
|
||||
setInfoU.setParentNode(rootV);
|
||||
}
|
||||
|
||||
private void unionByRank(int rootU, int rootV) {
|
||||
DisjointSetInfo setInfoU = nodes.get(rootU);
|
||||
DisjointSetInfo setInfoV = nodes.get(rootV);
|
||||
int rankU = setInfoU.getRank();
|
||||
int rankV = setInfoV.getRank();
|
||||
if (rankU < rankV) {
|
||||
setInfoU.setParentNode(rootV);
|
||||
} else {
|
||||
setInfoV.setParentNode(rootU);
|
||||
if (rankU == rankV) {
|
||||
setInfoU.setRank(rankU + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.algorithms.kruskal;
|
||||
|
||||
public class DisjointSetInfo {
|
||||
|
||||
private Integer parentNode;
|
||||
private int rank;
|
||||
|
||||
DisjointSetInfo(Integer nodeNumber) {
|
||||
setParentNode(nodeNumber);
|
||||
setRank(1);
|
||||
}
|
||||
|
||||
public Integer getParentNode() {
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
public void setParentNode(Integer parentNode) {
|
||||
this.parentNode = parentNode;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
this.rank = rank;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.algorithms.kruskal;
|
||||
|
||||
import com.google.common.graph.EndpointPair;
|
||||
import com.google.common.graph.MutableValueGraph;
|
||||
import com.google.common.graph.ValueGraph;
|
||||
import com.google.common.graph.ValueGraphBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class Kruskal {
|
||||
|
||||
public ValueGraph<Integer, Double> minSpanningTree(ValueGraph<Integer, Double> graph) {
|
||||
|
||||
return spanningTree(graph, true);
|
||||
}
|
||||
|
||||
public ValueGraph<Integer, Double> maxSpanningTree(ValueGraph<Integer, Double> graph) {
|
||||
return spanningTree(graph, false);
|
||||
}
|
||||
|
||||
private ValueGraph<Integer, Double> spanningTree(ValueGraph<Integer, Double> graph, boolean minSpanningTree) {
|
||||
Set<EndpointPair<Integer>> edges = graph.edges();
|
||||
List<EndpointPair<Integer>> edgeList = new ArrayList<>(edges);
|
||||
|
||||
if (minSpanningTree) {
|
||||
edgeList.sort(Comparator.comparing(e -> graph.edgeValue(e).get()));
|
||||
} else {
|
||||
edgeList.sort(Collections.reverseOrder(Comparator.comparing(e -> graph.edgeValue(e).get())));
|
||||
}
|
||||
|
||||
int totalNodes = graph.nodes().size();
|
||||
CycleDetector cycleDetector = new CycleDetector(totalNodes);
|
||||
int edgeCount = 0;
|
||||
|
||||
MutableValueGraph<Integer, Double> spanningTree = ValueGraphBuilder.undirected().build();
|
||||
for (EndpointPair<Integer> edge : edgeList) {
|
||||
if (cycleDetector.detectCycle(edge.nodeU(), edge.nodeV())) {
|
||||
continue;
|
||||
}
|
||||
spanningTree.putEdgeValue(edge.nodeU(), edge.nodeV(), graph.edgeValue(edge).get());
|
||||
edgeCount++;
|
||||
if (edgeCount == totalNodes - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return spanningTree;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class HeapNode {
|
||||
|
||||
int element;
|
||||
int arrayIndex;
|
||||
int nextElementIndex = 1;
|
||||
|
||||
public HeapNode(int element, int arrayIndex) {
|
||||
this.element = element;
|
||||
this.arrayIndex = arrayIndex;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
public class MinHeap {
|
||||
|
||||
HeapNode[] heapNodes;
|
||||
|
||||
public MinHeap(HeapNode heapNodes[]) {
|
||||
this.heapNodes = heapNodes;
|
||||
heapifyFromLastLeafsParent();
|
||||
}
|
||||
|
||||
void heapifyFromLastLeafsParent() {
|
||||
int lastLeafsParentIndex = getParentNodeIndex(heapNodes.length);
|
||||
while (lastLeafsParentIndex >= 0) {
|
||||
heapify(lastLeafsParentIndex);
|
||||
lastLeafsParentIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
void heapify(int index) {
|
||||
int leftNodeIndex = getLeftNodeIndex(index);
|
||||
int rightNodeIndex = getRightNodeIndex(index);
|
||||
int smallestElementIndex = index;
|
||||
if (leftNodeIndex < heapNodes.length && heapNodes[leftNodeIndex].element < heapNodes[index].element) {
|
||||
smallestElementIndex = leftNodeIndex;
|
||||
}
|
||||
if (rightNodeIndex < heapNodes.length && heapNodes[rightNodeIndex].element < heapNodes[smallestElementIndex].element) {
|
||||
smallestElementIndex = rightNodeIndex;
|
||||
}
|
||||
if (smallestElementIndex != index) {
|
||||
swap(index, smallestElementIndex);
|
||||
heapify(smallestElementIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int getParentNodeIndex(int index) {
|
||||
return (index - 1) / 2;
|
||||
}
|
||||
|
||||
int getLeftNodeIndex(int index) {
|
||||
return (2 * index + 1);
|
||||
}
|
||||
|
||||
int getRightNodeIndex(int index) {
|
||||
return (2 * index + 2);
|
||||
}
|
||||
|
||||
HeapNode getRootNode() {
|
||||
return heapNodes[0];
|
||||
}
|
||||
|
||||
void heapifyFromRoot() {
|
||||
heapify(0);
|
||||
}
|
||||
|
||||
void swap(int i, int j) {
|
||||
HeapNode temp = heapNodes[i];
|
||||
heapNodes[i] = heapNodes[j];
|
||||
heapNodes[j] = temp;
|
||||
}
|
||||
|
||||
static int[] merge(int[][] array) {
|
||||
HeapNode[] heapNodes = new HeapNode[array.length];
|
||||
int resultingArraySize = 0;
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
HeapNode node = new HeapNode(array[i][0], i);
|
||||
heapNodes[i] = node;
|
||||
resultingArraySize += array[i].length;
|
||||
}
|
||||
|
||||
MinHeap minHeap = new MinHeap(heapNodes);
|
||||
int[] resultingArray = new int[resultingArraySize];
|
||||
|
||||
for (int i = 0; i < resultingArraySize; i++) {
|
||||
HeapNode root = minHeap.getRootNode();
|
||||
resultingArray[i] = root.element;
|
||||
|
||||
if (root.nextElementIndex < array[root.arrayIndex].length) {
|
||||
root.element = array[root.arrayIndex][root.nextElementIndex++];
|
||||
} else {
|
||||
root.element = Integer.MAX_VALUE;
|
||||
}
|
||||
minHeap.heapifyFromRoot();
|
||||
}
|
||||
return resultingArray;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.algorithms.balancedbrackets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BalancedBracketsUsingDequeUnitTest {
|
||||
private BalancedBracketsUsingDeque balancedBracketsUsingDeque;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
balancedBracketsUsingDeque = new BalancedBracketsUsingDeque();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNullInput_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced(null);
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptyString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidCharacterString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("abc[](){}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOddLengthString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{{[]()}}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{{[]()}}}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthUnbalancedString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{[(])}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{[()]}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{{[[(())]]}}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnotherBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{{([])}}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnBalancedString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingDeque.isBalanced("{{)[](}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package com.baeldung.algorithms.balancedbrackets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class BalancedBracketsUsingStringUnitTest {
|
||||
private BalancedBracketsUsingString balancedBracketsUsingString;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
balancedBracketsUsingString = new BalancedBracketsUsingString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNullInput_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced(null);
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptyString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidCharacterString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("abc[](){}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOddLengthString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{{[]()}}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{{[]()}}}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthUnbalancedString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{[(])}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEvenLengthBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{[()]}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{{[[(())]]}}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnotherBalancedString_whenCheckingForBalance_shouldReturnTrue() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{{([])}}");
|
||||
assertThat(result).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUnBalancedString_whenCheckingForBalance_shouldReturnFalse() {
|
||||
boolean result = balancedBracketsUsingString.isBalanced("{{)[](}}");
|
||||
assertThat(result).isFalse();
|
||||
}
|
||||
|
||||
}
|
|
@ -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,58 @@
|
|||
package com.baeldung.algorithms.greedy;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class GreedyAlgorithmUnitTest {
|
||||
|
||||
private SocialConnector prepareNetwork() {
|
||||
SocialConnector sc = new SocialConnector();
|
||||
SocialUser root = new SocialUser("root");
|
||||
SocialUser child1 = new SocialUser("child1");
|
||||
SocialUser child2 = new SocialUser("child2");
|
||||
SocialUser child3 = new SocialUser("child3");
|
||||
SocialUser child21 = new SocialUser("child21");
|
||||
SocialUser child211 = new SocialUser("child211");
|
||||
SocialUser child2111 = new SocialUser("child2111");
|
||||
SocialUser child31 = new SocialUser("child31");
|
||||
SocialUser child311 = new SocialUser("child311");
|
||||
SocialUser child3111 = new SocialUser("child3111");
|
||||
child211.addFollowers(Arrays.asList(new SocialUser[]{child2111}));
|
||||
child311.addFollowers(Arrays.asList(new SocialUser[]{child3111}));
|
||||
child21.addFollowers(Arrays.asList(new SocialUser[]{child211}));
|
||||
child31.addFollowers(Arrays.asList(new SocialUser[]{child311,
|
||||
new SocialUser("child312"), new SocialUser("child313"), new SocialUser("child314")}));
|
||||
child1.addFollowers(Arrays.asList(new SocialUser[]{new SocialUser("child11"), new SocialUser("child12")}));
|
||||
child2.addFollowers(Arrays.asList(new SocialUser[]{child21, new SocialUser("child22"), new SocialUser("child23")}));
|
||||
child3.addFollowers(Arrays.asList(new SocialUser[]{child31}));
|
||||
root.addFollowers(Arrays.asList(new SocialUser[]{child1, child2, child3}));
|
||||
sc.setUsers(Arrays.asList(new SocialUser[]{root, child1, child2, child3, child21, child31, child311, child211}));
|
||||
return sc;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void greedyAlgorithmTest() {
|
||||
GreedyAlgorithm ga = new GreedyAlgorithm(prepareNetwork());
|
||||
assertEquals(ga.findMostFollowersPath("root"), 5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nongreedyAlgorithmTest() {
|
||||
NonGreedyAlgorithm nga = new NonGreedyAlgorithm(prepareNetwork(), 0);
|
||||
Assertions.assertThrows(IllegalStateException.class, () -> {
|
||||
nga.findMostFollowersPath("root");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nongreedyAlgorithmUnboundedTest() {
|
||||
SocialConnector sc = prepareNetwork();
|
||||
sc.switchCounter();
|
||||
NonGreedyAlgorithm nga = new NonGreedyAlgorithm(sc, 0);
|
||||
assertEquals(nga.findMostFollowersPath("root"), 6);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.baeldung.algorithms.kruskal;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import com.google.common.graph.MutableValueGraph;
|
||||
import com.google.common.graph.ValueGraph;
|
||||
import com.google.common.graph.ValueGraphBuilder;
|
||||
import com.baeldung.algorithms.kruskal.Kruskal;
|
||||
|
||||
public class KruskalUnitTest {
|
||||
|
||||
private MutableValueGraph<Integer, Double> graph;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
graph = ValueGraphBuilder.undirected().build();
|
||||
graph.putEdgeValue(0, 1, 8.0);
|
||||
graph.putEdgeValue(0, 2, 5.0);
|
||||
graph.putEdgeValue(1, 2, 9.0);
|
||||
graph.putEdgeValue(1, 3, 11.0);
|
||||
graph.putEdgeValue(2, 3, 15.0);
|
||||
graph.putEdgeValue(2, 4, 10.0);
|
||||
graph.putEdgeValue(3, 4, 7.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenMinimumSpanningTree_thenOutputCorrectResult() {
|
||||
final Kruskal kruskal = new Kruskal();
|
||||
ValueGraph<Integer, Double> spanningTree = kruskal.minSpanningTree(graph);
|
||||
|
||||
assertTrue(spanningTree.hasEdgeConnecting(0, 1));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(0, 2));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(2, 4));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(3, 4));
|
||||
assertEquals(graph.edgeValue(0, 1), spanningTree.edgeValue(0, 1));
|
||||
assertEquals(graph.edgeValue(0, 2), spanningTree.edgeValue(0, 2));
|
||||
assertEquals(graph.edgeValue(2, 4), spanningTree.edgeValue(2, 4));
|
||||
assertEquals(graph.edgeValue(3, 4), spanningTree.edgeValue(3, 4));
|
||||
|
||||
assertFalse(spanningTree.hasEdgeConnecting(1, 2));
|
||||
assertFalse(spanningTree.hasEdgeConnecting(1, 3));
|
||||
assertFalse(spanningTree.hasEdgeConnecting(2, 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenGraph_whenMaximumSpanningTree_thenOutputCorrectResult() {
|
||||
final Kruskal kruskal = new Kruskal();
|
||||
ValueGraph<Integer, Double> spanningTree = kruskal.maxSpanningTree(graph);
|
||||
|
||||
assertTrue(spanningTree.hasEdgeConnecting(0, 1));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(1, 3));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(2, 3));
|
||||
assertTrue(spanningTree.hasEdgeConnecting(2, 4));
|
||||
assertEquals(graph.edgeValue(0, 1), spanningTree.edgeValue(0, 1));
|
||||
assertEquals(graph.edgeValue(1, 3), spanningTree.edgeValue(1, 3));
|
||||
assertEquals(graph.edgeValue(2, 3), spanningTree.edgeValue(2, 3));
|
||||
assertEquals(graph.edgeValue(2, 4), spanningTree.edgeValue(2, 4));
|
||||
|
||||
assertFalse(spanningTree.hasEdgeConnecting(0, 2));
|
||||
assertFalse(spanningTree.hasEdgeConnecting(1, 2));
|
||||
assertFalse(spanningTree.hasEdgeConnecting(3, 4));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.algorithms.minheapmerge;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class MinHeapUnitTest {
|
||||
|
||||
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 };
|
||||
|
||||
@Test
|
||||
public void givenSortedArrays_whenMerged_thenShouldReturnASingleSortedarray() {
|
||||
int[] resultArray = MinHeap.merge(inputArray);
|
||||
|
||||
assertThat(resultArray.length, is(equalTo(10)));
|
||||
assertThat(resultArray, is(equalTo(expectedArray)));
|
||||
}
|
||||
|
||||
}
|
|
@ -9,3 +9,5 @@ This module contains articles about searching algorithms.
|
|||
- [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search)
|
||||
- [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms)
|
||||
- [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search)
|
||||
- [Range Search Algorithm in Java](https://www.baeldung.com/java-range-search)
|
||||
- [Fast Pattern Matching of Strings Using Suffix Tree](https://www.baeldung.com/java-pattern-matching-suffix-tree)
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>algorithms-searching</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.algorithms.quadtree;
|
||||
|
||||
public class Point {
|
||||
private float x;
|
||||
private float y;
|
||||
|
||||
public Point(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + x + " , " + y + "]";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package com.baeldung.algorithms.quadtree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class QuadTree {
|
||||
private static final int MAX_POINTS = 3;
|
||||
private Region area;
|
||||
private List<Point> points = new ArrayList<>();
|
||||
private List<QuadTree> quadTrees = new ArrayList<>();
|
||||
private StringBuilder searchTraversePath;
|
||||
|
||||
public QuadTree(Region area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public boolean addPoint(Point point) {
|
||||
if (this.area.containsPoint(point)) {
|
||||
if (this.points.size() < MAX_POINTS) {
|
||||
this.points.add(point);
|
||||
return true;
|
||||
} else {
|
||||
if (this.quadTrees.size() == 0) {
|
||||
createQuadrants();
|
||||
}
|
||||
return addPointToOneQuadrant(point);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean addPointToOneQuadrant(Point point) {
|
||||
boolean isPointAdded;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
isPointAdded = this.quadTrees.get(i)
|
||||
.addPoint(point);
|
||||
if (isPointAdded)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void createQuadrants() {
|
||||
Region region;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
region = this.area.getQuadrant(i);
|
||||
quadTrees.add(new QuadTree(region));
|
||||
}
|
||||
}
|
||||
|
||||
public List<Point> search(Region searchRegion, List<Point> matches, String depthIndicator) {
|
||||
searchTraversePath = new StringBuilder();
|
||||
if (matches == null) {
|
||||
matches = new ArrayList<Point>();
|
||||
searchTraversePath.append(depthIndicator)
|
||||
.append("Search Boundary =")
|
||||
.append(searchRegion)
|
||||
.append("\n");
|
||||
}
|
||||
if (!this.area.doesOverlap(searchRegion)) {
|
||||
return matches;
|
||||
} else {
|
||||
for (Point point : points) {
|
||||
if (searchRegion.containsPoint(point)) {
|
||||
searchTraversePath.append(depthIndicator)
|
||||
.append("Found match " + point)
|
||||
.append("\n");
|
||||
matches.add(point);
|
||||
}
|
||||
}
|
||||
if (this.quadTrees.size() > 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
searchTraversePath.append(depthIndicator)
|
||||
.append("Q")
|
||||
.append(i)
|
||||
.append("-->")
|
||||
.append(quadTrees.get(i).area)
|
||||
.append("\n");
|
||||
quadTrees.get(i)
|
||||
.search(searchRegion, matches, depthIndicator + "\t");
|
||||
this.searchTraversePath.append(quadTrees.get(i)
|
||||
.printSearchTraversePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
public String printTree(String depthIndicator) {
|
||||
String str = "";
|
||||
if (depthIndicator == "") {
|
||||
str += "Root-->" + area.toString() + "\n";
|
||||
}
|
||||
|
||||
for (Point point : points) {
|
||||
str += depthIndicator + point.toString() + "\n";
|
||||
}
|
||||
for (int i = 0; i < quadTrees.size(); i++) {
|
||||
str += depthIndicator + "Q" + String.valueOf(i) + "-->" + quadTrees.get(i).area.toString() + "\n";
|
||||
str += quadTrees.get(i)
|
||||
.printTree(depthIndicator + "\t");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public String printSearchTraversePath() {
|
||||
return searchTraversePath.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.baeldung.algorithms.quadtree;
|
||||
|
||||
public class Region {
|
||||
private float x1;
|
||||
private float y1;
|
||||
private float x2;
|
||||
private float y2;
|
||||
|
||||
public Region(float x1, float y1, float x2, float y2) {
|
||||
if (x1 >= x2 || y1 >= y2)
|
||||
throw new IllegalArgumentException("(x1,y1) should be lesser than (x2,y2)");
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.x2 = x2;
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
public Region getQuadrant(int quadrantIndex) {
|
||||
float quadrantWidth = (this.x2 - this.x1) / 2;
|
||||
float quadrantHeight = (this.y2 - this.y1) / 2;
|
||||
|
||||
// 0=SW, 1=NW, 2=NE, 3=SE
|
||||
switch (quadrantIndex) {
|
||||
case 0:
|
||||
return new Region(x1, y1, x1 + quadrantWidth, y1 + quadrantHeight);
|
||||
case 1:
|
||||
return new Region(x1, y1 + quadrantHeight, x1 + quadrantWidth, y2);
|
||||
case 2:
|
||||
return new Region(x1 + quadrantWidth, y1 + quadrantHeight, x2, y2);
|
||||
case 3:
|
||||
return new Region(x1 + quadrantWidth, y1, x2, y1 + quadrantHeight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean containsPoint(Point point) {
|
||||
// Consider left and top side to be inclusive for points on border
|
||||
return point.getX() >= this.x1
|
||||
&& point.getX() < this.x2
|
||||
&& point.getY() >= this.y1
|
||||
&& point.getY() < this.y2;
|
||||
}
|
||||
|
||||
public boolean doesOverlap(Region testRegion) {
|
||||
// Is test region completely to left of my region?
|
||||
if (testRegion.getX2() < this.getX1()) {
|
||||
return false;
|
||||
}
|
||||
// Is test region completely to right of my region?
|
||||
if (testRegion.getX1() > this.getX2()) {
|
||||
return false;
|
||||
}
|
||||
// Is test region completely above my region?
|
||||
if (testRegion.getY1() > this.getY2()) {
|
||||
return false;
|
||||
}
|
||||
// Is test region completely below my region?
|
||||
if (testRegion.getY2() < this.getY1()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[Region (x1=" + x1 + ", y1=" + y1 + "), (x2=" + x2 + ", y2=" + y2 + ")]";
|
||||
}
|
||||
|
||||
public float getX1() {
|
||||
return x1;
|
||||
}
|
||||
|
||||
public float getY1() {
|
||||
return y1;
|
||||
}
|
||||
|
||||
public float getX2() {
|
||||
return x2;
|
||||
}
|
||||
|
||||
public float getY2() {
|
||||
return y2;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.baeldung.algorithms.suffixtree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Node {
|
||||
private String text;
|
||||
private List<Node> children;
|
||||
private int position;
|
||||
|
||||
public Node(String word, int position) {
|
||||
this.text = word;
|
||||
this.position = position;
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public List<Node> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Node> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public String printTree(String depthIndicator) {
|
||||
String str = "";
|
||||
String positionStr = position > -1 ? "[" + String.valueOf(position) + "]" : "";
|
||||
str += depthIndicator + text + positionStr + "\n";
|
||||
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
str += children.get(i)
|
||||
.printTree(depthIndicator + "\t");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return printTree("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
package com.baeldung.algorithms.suffixtree;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SuffixTree {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTree.class);
|
||||
private static final String WORD_TERMINATION = "$";
|
||||
private static final int POSITION_UNDEFINED = -1;
|
||||
private Node root;
|
||||
private String fullText;
|
||||
|
||||
public SuffixTree(String text) {
|
||||
root = new Node("", POSITION_UNDEFINED);
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
addSuffix(text.substring(i) + WORD_TERMINATION, i);
|
||||
}
|
||||
fullText = text;
|
||||
}
|
||||
|
||||
public List<String> searchText(String pattern) {
|
||||
LOGGER.info("Searching for pattern \"{}\"", pattern);
|
||||
List<String> result = new ArrayList<>();
|
||||
List<Node> nodes = getAllNodesInTraversePath(pattern, root, false);
|
||||
|
||||
if (nodes.size() > 0) {
|
||||
Node lastNode = nodes.get(nodes.size() - 1);
|
||||
if (lastNode != null) {
|
||||
List<Integer> positions = getPositions(lastNode);
|
||||
positions = positions.stream()
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
positions.forEach(m -> result.add((markPatternInText(m, pattern))));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addSuffix(String suffix, int position) {
|
||||
LOGGER.info(">>>>>>>>>>>> Adding new suffix {}", suffix);
|
||||
List<Node> nodes = getAllNodesInTraversePath(suffix, root, true);
|
||||
if (nodes.size() == 0) {
|
||||
addChildNode(root, suffix, position);
|
||||
LOGGER.info("{}", printTree());
|
||||
} else {
|
||||
Node lastNode = nodes.remove(nodes.size() - 1);
|
||||
String newText = suffix;
|
||||
if (nodes.size() > 0) {
|
||||
String existingSuffixUptoLastNode = nodes.stream()
|
||||
.map(a -> a.getText())
|
||||
.reduce("", String::concat);
|
||||
|
||||
// Remove prefix from newText already included in parent
|
||||
newText = newText.substring(existingSuffixUptoLastNode.length());
|
||||
}
|
||||
extendNode(lastNode, newText, position);
|
||||
LOGGER.info("{}", printTree());
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> getPositions(Node node) {
|
||||
List<Integer> positions = new ArrayList<>();
|
||||
if (node.getText()
|
||||
.endsWith(WORD_TERMINATION)) {
|
||||
positions.add(node.getPosition());
|
||||
}
|
||||
for (int i = 0; i < node.getChildren()
|
||||
.size(); i++) {
|
||||
positions.addAll(getPositions(node.getChildren()
|
||||
.get(i)));
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
private String markPatternInText(Integer startPosition, String pattern) {
|
||||
String matchingTextLHS = fullText.substring(0, startPosition);
|
||||
String matchingText = fullText.substring(startPosition, startPosition + pattern.length());
|
||||
String matchingTextRHS = fullText.substring(startPosition + pattern.length());
|
||||
return matchingTextLHS + "[" + matchingText + "]" + matchingTextRHS;
|
||||
}
|
||||
|
||||
private void addChildNode(Node parentNode, String text, int position) {
|
||||
parentNode.getChildren()
|
||||
.add(new Node(text, position));
|
||||
}
|
||||
|
||||
private void extendNode(Node node, String newText, int position) {
|
||||
String currentText = node.getText();
|
||||
String commonPrefix = getLongestCommonPrefix(currentText, newText);
|
||||
|
||||
if (commonPrefix != currentText) {
|
||||
String parentText = currentText.substring(0, commonPrefix.length());
|
||||
String childText = currentText.substring(commonPrefix.length());
|
||||
splitNodeToParentAndChild(node, parentText, childText);
|
||||
}
|
||||
|
||||
String remainingText = newText.substring(commonPrefix.length());
|
||||
addChildNode(node, remainingText, position);
|
||||
}
|
||||
|
||||
private void splitNodeToParentAndChild(Node parentNode, String parentNewText, String childNewText) {
|
||||
Node childNode = new Node(childNewText, parentNode.getPosition());
|
||||
|
||||
if (parentNode.getChildren()
|
||||
.size() > 0) {
|
||||
while (parentNode.getChildren()
|
||||
.size() > 0) {
|
||||
childNode.getChildren()
|
||||
.add(parentNode.getChildren()
|
||||
.remove(0));
|
||||
}
|
||||
}
|
||||
|
||||
parentNode.getChildren()
|
||||
.add(childNode);
|
||||
parentNode.setText(parentNewText);
|
||||
parentNode.setPosition(POSITION_UNDEFINED);
|
||||
}
|
||||
|
||||
private String getLongestCommonPrefix(String str1, String str2) {
|
||||
int compareLength = Math.min(str1.length(), str2.length());
|
||||
for (int i = 0; i < compareLength; i++) {
|
||||
if (str1.charAt(i) != str2.charAt(i)) {
|
||||
return str1.substring(0, i);
|
||||
}
|
||||
}
|
||||
return str1.substring(0, compareLength);
|
||||
}
|
||||
|
||||
private List<Node> getAllNodesInTraversePath(String pattern, Node startNode, boolean isAllowPartialMatch) {
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
for (int i = 0; i < startNode.getChildren()
|
||||
.size(); i++) {
|
||||
Node currentNode = startNode.getChildren()
|
||||
.get(i);
|
||||
String nodeText = currentNode.getText();
|
||||
if (pattern.charAt(0) == nodeText.charAt(0)) {
|
||||
if (isAllowPartialMatch && pattern.length() <= nodeText.length()) {
|
||||
nodes.add(currentNode);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
int compareLength = Math.min(nodeText.length(), pattern.length());
|
||||
for (int j = 1; j < compareLength; j++) {
|
||||
if (pattern.charAt(j) != nodeText.charAt(j)) {
|
||||
if (isAllowPartialMatch) {
|
||||
nodes.add(currentNode);
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
nodes.add(currentNode);
|
||||
if (pattern.length() > compareLength) {
|
||||
List<Node> nodes2 = getAllNodesInTraversePath(pattern.substring(compareLength), currentNode, isAllowPartialMatch);
|
||||
if (nodes2.size() > 0) {
|
||||
nodes.addAll(nodes2);
|
||||
} else if (!isAllowPartialMatch) {
|
||||
nodes.add(null);
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public String printTree() {
|
||||
return root.printTree("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.algorithms.quadtree;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class QuadTreeSearchUnitTest {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(QuadTreeSearchUnitTest.class);
|
||||
|
||||
private static QuadTree quadTree;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
Region area = new Region(0, 0, 400, 400);
|
||||
quadTree = new QuadTree(area);
|
||||
|
||||
float[][] points = new float[][] { { 21, 25 }, { 55, 53 }, { 70, 318 }, { 98, 302 },
|
||||
{ 49, 229 }, { 135, 229 }, { 224, 292 }, { 206, 321 }, { 197, 258 }, { 245, 238 } };
|
||||
|
||||
for (int i = 0; i < points.length; i++) {
|
||||
Point point = new Point(points[i][0], points[i][1]);
|
||||
quadTree.addPoint(point);
|
||||
}
|
||||
LOGGER.info("\n" + quadTree.printTree(""));
|
||||
LOGGER.info("==============================================");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenQuadTree_whenSearchingForRange_thenReturn1MatchingItem() {
|
||||
Region searchArea = new Region(200, 200, 250, 250);
|
||||
List<Point> result = quadTree.search(searchArea, null, "");
|
||||
LOGGER.info(result.toString());
|
||||
LOGGER.info(quadTree.printSearchTraversePath());
|
||||
|
||||
Assert.assertEquals(1, result.size());
|
||||
Assert.assertArrayEquals(new float[] { 245, 238 },
|
||||
new float[]{result.get(0).getX(), result.get(0).getY() }, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenQuadTree_whenSearchingForRange_thenReturn2MatchingItems() {
|
||||
Region searchArea = new Region(0, 0, 100, 100);
|
||||
List<Point> result = quadTree.search(searchArea, null, "");
|
||||
LOGGER.info(result.toString());
|
||||
LOGGER.info(quadTree.printSearchTraversePath());
|
||||
|
||||
Assert.assertEquals(2, result.size());
|
||||
Assert.assertArrayEquals(new float[] { 21, 25 },
|
||||
new float[]{result.get(0).getX(), result.get(0).getY() }, 0);
|
||||
Assert.assertArrayEquals(new float[] { 55, 53 },
|
||||
new float[]{result.get(1).getX(), result.get(1).getY() }, 0);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package com.baeldung.algorithms.suffixtree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SuffixTreeUnitTest {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SuffixTreeUnitTest.class);
|
||||
|
||||
private static SuffixTree suffixTree;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
suffixTree = new SuffixTree("havanabanana");
|
||||
printTree();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForA_thenReturn6Matches() {
|
||||
List<String> matches = suffixTree.searchText("a");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] { "h[a]vanabanana", "hav[a]nabanana", "havan[a]banana", "havanab[a]nana", "havanaban[a]na", "havanabanan[a]" }, matches.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForNab_thenReturn1Match() {
|
||||
List<String> matches = suffixTree.searchText("nab");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] { "hava[nab]anana" }, matches.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForNag_thenReturnNoMatches() {
|
||||
List<String> matches = suffixTree.searchText("nag");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] {}, matches.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForBanana_thenReturn2Matches() {
|
||||
List<String> matches = suffixTree.searchText("ana");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] { "hav[ana]banana", "havanab[ana]na", "havanaban[ana]" }, matches.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForNa_thenReturn4Matches() {
|
||||
List<String> matches = suffixTree.searchText("na");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] { "hava[na]banana", "havanaba[na]na", "havanabana[na]" }, matches.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSuffixTree_whenSearchingForX_thenReturnNoMatches() {
|
||||
List<String> matches = suffixTree.searchText("x");
|
||||
matches.stream()
|
||||
.forEach(m -> LOGGER.info(m));
|
||||
Assert.assertArrayEquals(new String[] {}, matches.toArray());
|
||||
}
|
||||
|
||||
private static void printTree() {
|
||||
suffixTree.printTree();
|
||||
|
||||
LOGGER.info("\n" + suffixTree.printTree());
|
||||
LOGGER.info("==============================================");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [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)
|
||||
- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
|
||||
- [Partitioning and Sorting Arrays with Many Repeated Entries](https://www.baeldung.com/java-sorting-arrays-with-repeated-entries)
|
||||
- More articles: [[<-- prev]](/algorithms-sorting)
|
|
@ -0,0 +1,66 @@
|
|||
<project
|
||||
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>
|
||||
<artifactId>algorithms-sorting-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>algorithms-sorting-2</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-math3</artifactId>
|
||||
<version>${commons-math3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit-jupiter-api.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${org.assertj.core.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>${exec-maven-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<commons-math3.version>3.6.1</commons-math3.version>
|
||||
<org.assertj.core.version>3.9.0</org.assertj.core.version>
|
||||
<commons-codec.version>1.11</commons-codec.version>
|
||||
<junit-jupiter-api.version>5.3.1</junit-jupiter-api.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.algorithms.sort.bynumber;
|
||||
package com.baeldung.algorithms.bynumber;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
import static com.baeldung.algorithms.quicksort.SortingUtils.swap;
|
||||
|
||||
public class BentleyMcIlroyPartioning {
|
||||
|
||||
public static Partition partition(int input[], int begin, int end) {
|
||||
int left = begin, right = end;
|
||||
int leftEqualKeysCount = 0, rightEqualKeysCount = 0;
|
||||
|
||||
int partitioningValue = input[end];
|
||||
|
||||
while (true) {
|
||||
while (input[left] < partitioningValue)
|
||||
left++;
|
||||
|
||||
while (input[right] > partitioningValue) {
|
||||
if (right == begin)
|
||||
break;
|
||||
right--;
|
||||
}
|
||||
|
||||
if (left == right && input[left] == partitioningValue) {
|
||||
swap(input, begin + leftEqualKeysCount, left);
|
||||
leftEqualKeysCount++;
|
||||
left++;
|
||||
}
|
||||
|
||||
if (left >= right) {
|
||||
break;
|
||||
}
|
||||
|
||||
swap(input, left, right);
|
||||
|
||||
if (input[left] == partitioningValue) {
|
||||
swap(input, begin + leftEqualKeysCount, left);
|
||||
leftEqualKeysCount++;
|
||||
}
|
||||
|
||||
if (input[right] == partitioningValue) {
|
||||
swap(input, right, end - rightEqualKeysCount);
|
||||
rightEqualKeysCount++;
|
||||
}
|
||||
left++; right--;
|
||||
}
|
||||
right = left - 1;
|
||||
for (int k = begin; k < begin + leftEqualKeysCount; k++, right--) {
|
||||
if (right >= begin + leftEqualKeysCount)
|
||||
swap(input, k, right);
|
||||
}
|
||||
for (int k = end; k > end - rightEqualKeysCount; k--, left++) {
|
||||
if (left <= end - rightEqualKeysCount)
|
||||
swap(input, left, k);
|
||||
}
|
||||
return new Partition(right + 1, left - 1);
|
||||
}
|
||||
|
||||
public static void quicksort(int input[], int begin, int end) {
|
||||
if (end <= begin)
|
||||
return;
|
||||
Partition middlePartition = partition(input, begin, end);
|
||||
quicksort(input, begin, middlePartition.getLeft() - 1);
|
||||
quicksort(input, middlePartition.getRight() + 1, end);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
import static com.baeldung.algorithms.quicksort.SortingUtils.compare;
|
||||
import static com.baeldung.algorithms.quicksort.SortingUtils.swap;
|
||||
|
||||
public class DutchNationalFlagPartioning {
|
||||
|
||||
public static Partition partition(int[] a, int begin, int end) {
|
||||
int lt = begin, current = begin, gt = end;
|
||||
int partitioningValue = a[begin];
|
||||
|
||||
while (current <= gt) {
|
||||
int compareCurrent = compare(a[current], partitioningValue);
|
||||
switch (compareCurrent) {
|
||||
case -1:
|
||||
swap(a, current++, lt++);
|
||||
break;
|
||||
case 0:
|
||||
current++;
|
||||
break;
|
||||
case 1:
|
||||
swap(a, current, gt--);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Partition(lt, gt);
|
||||
}
|
||||
|
||||
public static void quicksort(int[] input, int begin, int end) {
|
||||
if (end <= begin)
|
||||
return;
|
||||
|
||||
Partition middlePartition = partition(input, begin, end);
|
||||
|
||||
quicksort(input, begin, middlePartition.getLeft() - 1);
|
||||
quicksort(input, middlePartition.getRight() + 1, end);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
public class Partition {
|
||||
private int left;
|
||||
private int right;
|
||||
|
||||
public Partition(int left, int right) {
|
||||
super();
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public int getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public void setLeft(int left) {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public int getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public void setRight(int right) {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
public class SortingUtils {
|
||||
|
||||
public static void swap(int[] array, int position1, int position2) {
|
||||
if (position1 != position2) {
|
||||
int temp = array[position1];
|
||||
array[position1] = array[position2];
|
||||
array[position2] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static int compare(int num1, int num2) {
|
||||
if (num1 > num2)
|
||||
return 1;
|
||||
else if (num1 < num2)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void printArray(int[] array) {
|
||||
if (array == null) {
|
||||
return;
|
||||
}
|
||||
for (int e : array) {
|
||||
System.out.print(e + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -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 java.util.ArrayList;
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BentleyMcilroyPartitioningUnitTest {
|
||||
|
||||
@Test
|
||||
public void given_IntegerArray_whenSortedWithBentleyMcilroyPartitioning_thenGetSortedArray() {
|
||||
int[] actual = {3, 2, 2, 2, 3, 7, 7, 3, 2, 2, 7, 3, 3};
|
||||
int[] expected = {2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 7, 7, 7};
|
||||
BentleyMcIlroyPartioning.quicksort(actual, 0, actual.length - 1);
|
||||
Assert.assertArrayEquals(expected, actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.algorithms.quicksort;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DNFThreeWayQuickSortUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenIntegerArray_whenSortedWithThreeWayQuickSort_thenGetSortedArray() {
|
||||
int[] actual = {3, 5, 5, 5, 3, 7, 7, 3, 5, 5, 7, 3, 3};
|
||||
int[] expected = {3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 7, 7, 7};
|
||||
DutchNationalFlagPartioning.quicksort(actual, 0, actual.length - 1);
|
||||
Assert.assertArrayEquals(expected, actual);
|
||||
}
|
||||
}
|
|
@ -11,10 +11,7 @@ This module contains articles about sorting algorithms.
|
|||
- [Heap Sort in Java](https://www.baeldung.com/java-heap-sort)
|
||||
- [Shell Sort in Java](https://www.baeldung.com/java-shell-sort)
|
||||
- [Counting Sort in Java](https://www.baeldung.com/java-counting-sort)
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [How an In-Place Sorting Algorithm Works](https://www.baeldung.com/java-in-place-sorting)
|
||||
- [Selection Sort in Java](https://www.baeldung.com/java-selection-sort)
|
||||
- [Sorting Strings by Contained Numbers in Java](https://www.baeldung.com/java-sort-strings-contained-numbers)
|
||||
- [Radix Sort in Java](https://www.baeldung.com/java-radix-sort)
|
||||
- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
|
||||
- [Bucket Sort in Java](https://www.baeldung.com/java-bucket-sort)
|
||||
- More articles: [[next -->]](/algorithms-sorintg-2)
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-sorting</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>animal-sniffer-mvn-plugin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
@ -44,5 +46,5 @@
|
|||
<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>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project
|
||||
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>
|
||||
<artifactId>annotation-processing</artifactId>
|
||||
<name>annotation-processing</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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>annotation-user</artifactId>
|
||||
<name>annotation-user</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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>annotations</artifactId>
|
||||
<name>annotations</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>antlr</artifactId>
|
||||
<name>antlr</name>
|
||||
|
@ -58,5 +60,5 @@
|
|||
<antlr.version>4.7.1</antlr.version>
|
||||
<mojo.version>3.0.0</mojo.version>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
|
@ -1,7 +1,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"
|
||||
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"
|
||||
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>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Apache Beam](https://www.baeldung.com/apache-beam)
|
|
@ -0,0 +1,43 @@
|
|||
<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>
|
|
@ -0,0 +1,71 @@
|
|||
package com.baeldung.apache.beam.intro;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.beam.sdk.Pipeline;
|
||||
import org.apache.beam.sdk.io.TextIO;
|
||||
import org.apache.beam.sdk.options.PipelineOptions;
|
||||
import org.apache.beam.sdk.options.PipelineOptionsFactory;
|
||||
import org.apache.beam.sdk.transforms.Count;
|
||||
import org.apache.beam.sdk.transforms.Filter;
|
||||
import org.apache.beam.sdk.transforms.FlatMapElements;
|
||||
import org.apache.beam.sdk.transforms.MapElements;
|
||||
import org.apache.beam.sdk.values.KV;
|
||||
import org.apache.beam.sdk.values.PCollection;
|
||||
import org.apache.beam.sdk.values.TypeDescriptors;
|
||||
|
||||
public class WordCount {
|
||||
|
||||
public static boolean wordCount(String inputFilePath, String outputFilePath) {
|
||||
// We use default options
|
||||
PipelineOptions options = PipelineOptionsFactory.create();
|
||||
// to create the pipeline
|
||||
Pipeline p = Pipeline.create(options);
|
||||
// Here is our workflow graph
|
||||
PCollection<KV<String, Long>> wordCount = p
|
||||
.apply("(1) Read all lines", TextIO.read().from(inputFilePath))
|
||||
.apply("(2) Flatmap to a list of words", FlatMapElements.into(TypeDescriptors.strings())
|
||||
.via(line -> Arrays.asList(line.split("\\s"))))
|
||||
.apply("(3) Lowercase all", MapElements.into(TypeDescriptors.strings())
|
||||
.via(word -> word.toLowerCase()))
|
||||
.apply("(4) Trim punctuations", MapElements.into(TypeDescriptors.strings())
|
||||
.via(word -> trim(word)))
|
||||
.apply("(5) Filter stopwords", Filter.by(word -> !isStopWord(word)))
|
||||
.apply("(6) Count words", Count.perElement());
|
||||
// We convert the PCollection to String so that we can write it to file
|
||||
wordCount.apply(MapElements.into(TypeDescriptors.strings())
|
||||
.via(count -> count.getKey() + " --> " + count.getValue()))
|
||||
.apply(TextIO.write().to(outputFilePath));
|
||||
// Finally we must run the pipeline, otherwise it's only a definition
|
||||
p.run().waitUntilFinish();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isStopWord(String word) {
|
||||
String[] stopwords = {"am", "are", "is", "i", "you", "me",
|
||||
"he", "she", "they", "them", "was",
|
||||
"were", "from", "in", "of", "to", "be",
|
||||
"him", "her", "us", "and", "or"};
|
||||
for (String stopword : stopwords) {
|
||||
if (stopword.compareTo(word) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String trim(String word) {
|
||||
return word.replace("(","")
|
||||
.replace(")", "")
|
||||
.replace(",", "")
|
||||
.replace(".", "")
|
||||
.replace("\"", "")
|
||||
.replace("'", "")
|
||||
.replace(":", "")
|
||||
.replace(";", "")
|
||||
.replace("-", "")
|
||||
.replace("?", "")
|
||||
.replace("!", "");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.apache.beam.intro;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.apache.beam.intro.WordCount;
|
||||
|
||||
public class WordCountUnitTest {
|
||||
|
||||
@Test
|
||||
// @Ignore
|
||||
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
|
||||
boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
|
||||
assertTrue(jobDone);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
We've all heard the scare stories about North Korea: the homemade nuclear arsenal built while their people starve and then aimed imprecisely at the rest of the world, a
|
||||
leader so deluded he makes L Ron Hubbard look like a man excessively overburdened with self-doubt and their deep-seated belief that foreign capitalists will invade at any
|
||||
moment and steal all their bauxite.
|
||||
The popular portrayal of this Marxist nation is something like one of the more harrowing episodes of M*A*S*H, only with the cast of wacky characters replaced by twitchy,
|
||||
heavily armed Stalinist meth addicts
|
||||
Cracked would like to take a moment to celebrate the good things about North Korea though, the things that the country's enemies prefer to suppress as part of their politically
|
||||
motivated jealousy. Like how no different to you and me, there's nothing every North Korean likes more after an 18 hour shift at the phosphorus plant than a nice beer to go with
|
||||
his dried fish ration. Ever attentive to its people's needs and in the twinkling of a decade, North Korea's leadership bought, disassembled, transported and rebuilt a British
|
||||
brewery in order to discover and reproduce the secrets of beer and then brew the sweet nectar for its hardworking people, up to 18 bottles at a time. And with minimal fatalities.
|
||||
When was the last time YOUR leader got a beer for YOU, American? (NB do not answer this question if you are Henry Louis Gates).
|
||||
Or how about the fried chicken restaurant that downtown Pyongyang boasts? Yes real chicken, fried and then delivered to your sleeping cube, with optional beer if you like! You
|
||||
don't even have to remove the feathers or pull out the gizzard yourself. Mostly. Americans must eat their fried chicken from a bucket, like swine, sold by a company so secretive
|
||||
that even the very blend of seasoning used is intentionally kept from them. And they call North Korea paranoid?
|
||||
And how many nations would entertain the syphilitic, bourgeois ramblings of Bill Clinton let alone permit him anywhere near their proud womenfolk? Only wise Kim Jong Il could see
|
||||
past Bill's many, many imperfections and treat him with the pity and kindness he deserves, accepting his feeble pleas to pardon the American spies rightly convicted of photographing
|
||||
the nation's sensitive beetroot fields.
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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>
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
### 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"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cxf-aegis</artifactId>
|
||||
<name>cxf-aegis</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cxf-introduction</artifactId>
|
||||
<name>cxf-introduction</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cxf-jaxrs-implementation</artifactId>
|
||||
<name>cxf-jaxrs-implementation</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cxf-spring</artifactId>
|
||||
<name>cxf-spring</name>
|
||||
|
|
|
@ -1,6 +1,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"
|
||||
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"
|
||||
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-cxf</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue